From: Numan Siddique <num...@ovn.org>

Signed-off-by: Numan Siddique <num...@ovn.org>
---
 br-controller/automake.mk         |   6 +-
 br-controller/en-bridge-data.c    | 122 +++++++++++++++++++++++++++++-
 br-controller/en-bridge-data.h    |  23 ++++++
 br-controller/ovn-br-controller.c |   4 +
 4 files changed, 148 insertions(+), 7 deletions(-)

diff --git a/br-controller/automake.mk b/br-controller/automake.mk
index 497f440551..b77e2abcff 100644
--- a/br-controller/automake.mk
+++ b/br-controller/automake.mk
@@ -1,10 +1,10 @@
 bin_PROGRAMS += br-controller/ovn-br-controller
 br_controller_ovn_br_controller_SOURCES = \
-       br-controller/ovn-br-controller.c \
+       br-controller/en-bridge-data.c \
+       br-controller/en-bridge-data.h \
        br-controller/en-lflow.c \
        br-controller/en-lflow.h \
-       br-controller/en-bridge-data.c \
-       br-controller/en-bridge-data.h
+       br-controller/ovn-br-controller.c
 
 br_controller_ovn_br_controller_LDADD = lib/libovn.la 
$(OVS_LIBDIR)/libopenvswitch.la
 man_MANS += br-controller/ovn-br-controller.8
diff --git a/br-controller/en-bridge-data.c b/br-controller/en-bridge-data.c
index 293ae895c0..483c784a37 100644
--- a/br-controller/en-bridge-data.c
+++ b/br-controller/en-bridge-data.c
@@ -19,27 +19,141 @@
 #include <stdio.h>
 
 /* OVS includes. */
+#include "include/openvswitch/hmap.h"
+#include "include/openvswitch/shash.h"
+#include "lib/vswitch-idl.h"
 #include "openvswitch/vlog.h"
 
 /* OVN includes. */
 #include "en-bridge-data.h"
+#include "lib/ovn-br-idl.h"
 
 VLOG_DEFINE_THIS_MODULE(en_bridge_data);
 
+static void ovn_bridges_init(struct shash *);
+static void ovn_bridges_cleanup(struct shash *);
+static void ovn_bridges_run(const struct ovnbrrec_bridge_table *,
+                            struct shash *bridges,
+                            struct ovsdb_idl_index *);
+static void ovn_bridge_destroy(struct ovn_bridge *);
+static const struct ovsrec_bridge *ovsbridge_lookup_by_name(
+    struct ovsdb_idl_index *ovsrec_bridge_by_name,
+    const char *name);
+static void build_ovn_bridge_iface_simap(struct ovn_bridge *);
+
 void *
 en_bridge_data_init(struct engine_node *node OVS_UNUSED,
                     struct engine_arg *arg OVS_UNUSED)
 {
-    return NULL;
+    struct ed_type_bridge_data *data = xzalloc(sizeof *data);
+    ovn_bridges_init(&data->bridges);
+
+    return data;
 }
 
 void
-en_bridge_data_cleanup(void *data OVS_UNUSED)
+en_bridge_data_cleanup(void *data_)
 {
+    struct ed_type_bridge_data *data = data_;
+    ovn_bridges_cleanup(&data->bridges);
 }
 
 enum engine_node_state
-en_bridge_data_run(struct engine_node *node OVS_UNUSED, void *data OVS_UNUSED)
+en_bridge_data_run(struct engine_node *node, void *data_)
+{
+    const struct ovnbrrec_bridge_table *ovnbrrec_br_table =
+        EN_OVSDB_GET(engine_get_input("BR_bridge", node));
+    struct ovsdb_idl_index *ovsrec_bridge_by_name =
+        engine_ovsdb_node_get_index(engine_get_input("OVS_bridge", node),
+                                    "name");
+    struct ed_type_bridge_data *data = data_;
+
+    ovn_bridges_cleanup(&data->bridges);
+    ovn_bridges_init(&data->bridges);
+    ovn_bridges_run(ovnbrrec_br_table, &data->bridges, ovsrec_bridge_by_name);
+
+    return EN_UPDATED;
+}
+
+/* Static functions. */
+static void
+ovn_bridges_init(struct shash *bridges)
 {
-    return EN_UNCHANGED;
+    shash_init(bridges);
+}
+
+static void
+ovn_bridges_cleanup(struct shash *bridges)
+{
+    struct shash_node *shash_node;
+    SHASH_FOR_EACH_SAFE (shash_node, bridges) {
+        ovn_bridge_destroy(shash_node->data);
+    }
+    shash_destroy(bridges);
+}
+
+static void
+ovn_bridges_run(const struct ovnbrrec_bridge_table *br_table,
+               struct shash *bridges,
+               struct ovsdb_idl_index *ovsrec_bridge_by_name)
+{
+    const struct ovnbrrec_bridge *db_br;
+    OVNBRREC_BRIDGE_TABLE_FOR_EACH (db_br, br_table) {
+        struct ovn_bridge *br = xzalloc(sizeof *br);
+        br->db_br = db_br;
+        br->key = db_br->header_.uuid;
+        simap_init(&br->ovs_ifaces);
+        shash_add(bridges, db_br->name, br);
+
+        const struct ovsrec_bridge *ovs_br =
+            ovsbridge_lookup_by_name(ovsrec_bridge_by_name, db_br->name);
+
+        if (!ovs_br) {
+            continue;
+        }
+
+        br->ovs_br = ovs_br;
+        build_ovn_bridge_iface_simap(br);
+    }
+}
+
+static void
+ovn_bridge_destroy(struct ovn_bridge *br)
+{
+    simap_destroy(&br->ovs_ifaces);
+    free(br);
+}
+
+static const struct ovsrec_bridge *
+ovsbridge_lookup_by_name(struct ovsdb_idl_index *ovsrec_bridge_by_name,
+                         const char *name)
+{
+    struct ovsrec_bridge *target =
+        ovsrec_bridge_index_init_row(ovsrec_bridge_by_name);
+    ovsrec_bridge_index_set_name(target, name);
+
+    const struct ovsrec_bridge *retval =
+        ovsrec_bridge_index_find(ovsrec_bridge_by_name, target);
+    ovsrec_bridge_index_destroy_row(target);
+
+    return retval;
+}
+
+static void
+build_ovn_bridge_iface_simap(struct ovn_bridge *br)
+{
+    ovs_assert(br->ovs_br);
+    for (size_t i = 0; i < br->ovs_br->n_ports; i++) {
+        const struct ovsrec_port *port_rec = br->ovs_br->ports[i];
+
+        for (size_t j = 0; j < port_rec->n_interfaces; j++) {
+            const struct ovsrec_interface *iface_rec;
+
+            iface_rec = port_rec->interfaces[j];
+            int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
+            if (ofport) {
+                simap_put(&br->ovs_ifaces, iface_rec->name, ofport);
+            }
+        }
+    }
 }
diff --git a/br-controller/en-bridge-data.h b/br-controller/en-bridge-data.h
index 4a280b5cd1..b374798649 100644
--- a/br-controller/en-bridge-data.h
+++ b/br-controller/en-bridge-data.h
@@ -7,8 +7,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+/* OVS includes. */
+#include "lib/simap.h"
+#include "include/openvswitch/shash.h"
+#include "lib/uuid.h"
+
+/* OVN includes. */
 #include "lib/inc-proc-eng.h"
 
+struct ovnbrrec_bridge;
+struct ovsrec_bridge;
+
+struct ovn_bridge {
+    struct uuid key; /* ovnbrrec_bridge->header_.uuid */
+
+    const struct ovnbrrec_bridge *db_br;
+    const struct ovsrec_bridge *ovs_br;
+
+    /* simap of ovs interface names to ofport numbers. */
+    struct simap ovs_ifaces;
+};
+
+struct ed_type_bridge_data {
+    struct shash bridges;
+};
+
 enum engine_node_state en_bridge_data_run(struct engine_node *, void *data);
 void *en_bridge_data_init(struct engine_node *node, struct engine_arg *arg);
 void en_bridge_data_cleanup(void *data);
diff --git a/br-controller/ovn-br-controller.c 
b/br-controller/ovn-br-controller.c
index 27c5e28d0c..7cfe6ac23d 100644
--- a/br-controller/ovn-br-controller.c
+++ b/br-controller/ovn-br-controller.c
@@ -141,6 +141,9 @@ main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
     struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
         ovsdb_idl_create(ovs_remote, &ovsrec_idl_class, false, true));
     ctrl_register_ovs_idl(ovs_idl_loop.idl);
+    struct ovsdb_idl_index *ovsrec_bridge_by_name
+        = ovsdb_idl_index_create1(ovs_idl_loop.idl,
+                                  &ovsrec_bridge_col_name);
 
     ovsdb_idl_get_initial_snapshot(ovs_idl_loop.idl);
 
@@ -195,6 +198,7 @@ main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
         .ovnbr_idl = ovnbr_idl_loop.idl,
     };
     engine_init(&en_br_controller_output, &engine_arg);
+    engine_ovsdb_node_add_index(&en_ovs_bridge, "name", ovsrec_bridge_by_name);
 
     unsigned int ovs_cond_seqno = UINT_MAX;
     unsigned int ovnbr_cond_seqno = UINT_MAX;
-- 
2.50.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to