'struct ic_data' is used to hold the global state data for the
incremental processing node 'en_ic' and 'struct ic_input' this will
hold references to database tables and indexes. In order to achieve this,
we refactor in the following way:
* Move index and tables into the main 'ic' engine
* Adjust inputs of function 'ovn_db_run()' inside the ic engine which
  in turn ends up calling upon the functions that manage the main groups
  of actions spreading the new structures:
    gateway_run();
    enumerate_datapaths();
    ts_run();
    tr_run();
    port_binding_run();
    route_run();
    sync_service_monitor();
* Refactor ovn-ic.c to use 'struct ic_data' and 'struct ic_input'
  where applicable.

Signed-off-by: Paulo Guilherme Silva <[email protected]>
---
 ic/en-ic.c            | 168 ++++++++++-
 ic/en-ic.h            |   2 +-
 ic/inc-proc-ic.c      | 145 ++++++++-
 ic/inc-proc-ic.h      |   8 +-
 ic/ovn-ic.c           | 680 +++++++++++++++++++-----------------------
 ic/ovn-ic.h           |  50 +++-
 lib/stopwatch-names.h |   3 +
 7 files changed, 652 insertions(+), 404 deletions(-)

diff --git a/ic/en-ic.c b/ic/en-ic.c
index 2db9d3b84..ce7d5de76 100644
--- a/ic/en-ic.c
+++ b/ic/en-ic.c
@@ -18,33 +18,185 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+/* OVS includes. */
+#include "openvswitch/vlog.h"
+
+/* OVN includes. */
+#include "ovn-ic.h"
 #include "en-ic.h"
 #include "lib/inc-proc-eng.h"
+#include "lib/ovn-util.h"
 #include "lib/stopwatch-names.h"
-#include "ovn-ic.h"
-#include "openvswitch/vlog.h"
+#include "coverage.h"
+#include "stopwatch.h"
+#include "stopwatch-names.h"
 
 VLOG_DEFINE_THIS_MODULE(en_ic);
+COVERAGE_DEFINE(ic_run);
+
+void ic_destroy(struct ic_data *data);
+void ic_init(struct ic_data *data);
+
+static void
+ic_get_input_data(struct engine_node *node,
+                  struct ic_input *input_data)
+{
+    /* Table references */
+    input_data->nbrec_nb_global_table =
+        EN_OVSDB_GET(engine_get_input("NB_nb_global", node));
+    input_data->nbrec_logical_switch_table =
+        EN_OVSDB_GET(engine_get_input("NB_logical_switch", node));
+    input_data->nbrec_logical_router_table =
+        EN_OVSDB_GET(engine_get_input("NB_logical_router", node));
+    input_data->sbrec_sb_global_table =
+        EN_OVSDB_GET(engine_get_input("SB_sb_global", node));
+    input_data->sbrec_chassis_table =
+        EN_OVSDB_GET(engine_get_input("SB_chassis", node));
+    input_data->icnbrec_ic_nb_global_table =
+        EN_OVSDB_GET(engine_get_input("ICNB_ic_nb_global", node));
+    input_data->icnbrec_transit_switch_table =
+        EN_OVSDB_GET(engine_get_input("ICNB_transit_switch", node));
+    input_data->icnbrec_transit_router_table =
+        EN_OVSDB_GET(engine_get_input("ICNB_transit_router", node));
+    input_data->icsbrec_ic_sb_global_table =
+        EN_OVSDB_GET(engine_get_input("ICSB_ic_sb_global", node));
+    input_data->icsbrec_availability_zone_table =
+        EN_OVSDB_GET(engine_get_input("ICSB_availability_zone", node));
+    input_data->icsbrec_encap_table =
+        EN_OVSDB_GET(engine_get_input("ICSB_encap", node));
+    input_data->icsbrec_gateway_table =
+        EN_OVSDB_GET(engine_get_input("ICSB_gateway", node));
+    input_data->icsbrec_datapath_binding_table =
+        EN_OVSDB_GET(engine_get_input("ICSB_datapath_binding", node));
+
+    /* Indexes */
+    input_data->nbrec_ls_by_name =
+        engine_ovsdb_node_get_index(
+            engine_get_input("NB_logical_switch", node),
+            "nbrec_ls_by_name");
+    input_data->nbrec_lr_by_name =
+        engine_ovsdb_node_get_index(
+            engine_get_input("NB_logical_router", node),
+            "nbrec_lr_by_name");
+    input_data->nbrec_lrp_by_name =
+        engine_ovsdb_node_get_index(
+            engine_get_input("NB_logical_router", node),
+            "nbrec_lrp_by_name");
+    input_data->nbrec_port_by_name =
+        engine_ovsdb_node_get_index(
+            engine_get_input("NB_logical_switch", node),
+            "nbrec_port_by_name");
+    input_data->sbrec_chassis_by_name =
+        engine_ovsdb_node_get_index(
+            engine_get_input("SB_chassis", node),
+            "sbrec_chassis_by_name");
+    input_data->sbrec_port_binding_by_name =
+        engine_ovsdb_node_get_index(
+            engine_get_input("SB_port_binding", node),
+            "sbrec_port_binding_by_name");
+    input_data->sbrec_service_monitor_by_remote_type =
+        engine_ovsdb_node_get_index(
+            engine_get_input("SB_service_monitor", node),
+            "sbrec_service_monitor_by_remote_type");
+    input_data->sbrec_service_monitor_by_ic_learned =
+        engine_ovsdb_node_get_index(
+            engine_get_input("SB_service_monitor", node),
+            "sbrec_service_monitor_by_ic_learned");
+    input_data->sbrec_service_monitor_by_remote_type_logical_port =
+        engine_ovsdb_node_get_index(
+            engine_get_input("SB_service_monitor", node),
+            "sbrec_service_monitor_by_remote_type_logical_port");
+    input_data->icnbrec_transit_switch_by_name =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICNB_transit_switch", node),
+            "icnbrec_transit_switch_by_name");
+    input_data->icsbrec_port_binding_by_az =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_port_binding", node),
+            "icsbrec_port_binding_by_az");
+    input_data->icsbrec_port_binding_by_ts =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_port_binding", node),
+            "icsbrec_port_binding_by_ts");
+    input_data->icsbrec_port_binding_by_ts_az =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_port_binding", node),
+            "icsbrec_port_binding_by_ts_az");
+    input_data->icsbrec_route_by_az =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_route", node),
+            "icsbrec_route_by_az");
+    input_data->icsbrec_route_by_ts =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_route", node),
+            "icsbrec_route_by_ts");
+    input_data->icsbrec_route_by_ts_az =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_route", node),
+            "icsbrec_route_by_ts_az");
+    input_data->icsbrec_service_monitor_by_source_az =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_service_monitor", node),
+            "icsbrec_service_monitor_by_source_az");
+    input_data->icsbrec_service_monitor_by_target_az =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_service_monitor", node),
+            "icsbrec_service_monitor_by_target_az");
+    input_data->icsbrec_service_monitor_by_target_az_logical_port =
+        engine_ovsdb_node_get_index(
+            engine_get_input("ICSB_service_monitor", node),
+            "icsbrec_service_monitor_by_target_az_logical_port");
+}
 
 enum engine_node_state
-en_ic_run(struct engine_node *node OVS_UNUSED, void *data OVS_UNUSED)
+en_ic_run(struct engine_node *node, void *data)
 {
     const struct engine_context *eng_ctx = engine_get_context();
-    struct ic_context *ctx = eng_ctx->client_ctx;
 
-    ovn_db_run(ctx);
+    struct ic_input input_data;
+
+    ic_destroy(data);
+    ic_init(data);
 
+    ic_get_input_data(node, &input_data);
+    input_data.runned_az = eng_ctx->client_ctx;
+
+    COVERAGE_INC(ic_run);
+    stopwatch_start(IC_OVN_DB_RUN_STOPWATCH_NAME, time_msec());
+    ovn_db_run(&input_data, data, (struct engine_context *) eng_ctx);
+    stopwatch_stop(IC_OVN_DB_RUN_STOPWATCH_NAME, time_msec());
     return EN_UPDATED;
 }
 
 void *
 en_ic_init(struct engine_node *node OVS_UNUSED,
-            struct engine_arg *arg OVS_UNUSED)
+           struct engine_arg *arg OVS_UNUSED)
+{
+    struct ic_data *data = xzalloc(sizeof *data);
+
+    ic_init(data);
+
+    return data;
+}
+
+void
+en_ic_cleanup(void *data)
+{
+    ic_destroy(data);
+}
+
+void
+ic_destroy(struct ic_data *data)
 {
-    return NULL;
+    ovn_destroy_tnlids(&data->dp_tnlids);
+    shash_destroy(&data->isb_ts_dps);
+    shash_destroy(&data->isb_tr_dps);
 }
 
 void
-en_ic_cleanup(void *data OVS_UNUSED)
+ic_init(struct ic_data *data)
 {
+    hmap_init(&data->dp_tnlids);
+    shash_init(&data->isb_ts_dps);
+    shash_init(&data->isb_tr_dps);
 }
diff --git a/ic/en-ic.h b/ic/en-ic.h
index a4b75bb0e..ab1fbaf42 100644
--- a/ic/en-ic.h
+++ b/ic/en-ic.h
@@ -12,7 +12,7 @@
 enum engine_node_state en_ic_run(struct engine_node *node OVS_UNUSED,
                                  void *data OVS_UNUSED);
 void *en_ic_init(struct engine_node *node OVS_UNUSED,
-                 struct engine_arg *arg);
+                 struct engine_arg *arg OVS_UNUSED);
 void en_ic_cleanup(void *data);
 
 #endif /* EN_IC_H */
diff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c
index ba9fdeb9e..2f4579464 100644
--- a/ic/inc-proc-ic.c
+++ b/ic/inc-proc-ic.c
@@ -157,7 +157,7 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic);
 
 /* Define engine nodes for other nodes. They should be defined as static to
  * avoid sparse errors. */
-static ENGINE_NODE(ic);
+static ENGINE_NODE(ic, SB_WRITE);
 
 void inc_proc_ic_init(struct ovsdb_idl_loop *nb,
                       struct ovsdb_idl_loop *sb,
@@ -187,11 +187,11 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_ic, &en_icnb_transit_router, NULL);
     engine_add_input(&en_ic, &en_icnb_transit_router_port, NULL);
 
+    engine_add_input(&en_ic, &en_icsb_ic_sb_global, NULL);
+    engine_add_input(&en_ic, &en_icsb_availability_zone, NULL);
     engine_add_input(&en_ic, &en_icsb_encap, NULL);
     engine_add_input(&en_ic, &en_icsb_service_monitor, NULL);
-    engine_add_input(&en_ic, &en_icsb_ic_sb_global, NULL);
     engine_add_input(&en_ic, &en_icsb_port_binding, NULL);
-    engine_add_input(&en_ic, &en_icsb_availability_zone, NULL);
     engine_add_input(&en_ic, &en_icsb_gateway, NULL);
     engine_add_input(&en_ic, &en_icsb_route, NULL);
     engine_add_input(&en_ic, &en_icsb_datapath_binding, NULL);
@@ -203,22 +203,149 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,
         .icsb_idl = icsb->idl,
     };
 
+    /* create IDL indexes*/
+    struct ovsdb_idl_index *nbrec_ls_by_name
+        = ovsdb_idl_index_create1(nb->idl, &nbrec_logical_switch_col_name);
+    struct ovsdb_idl_index *nbrec_lr_by_name
+        = ovsdb_idl_index_create1(nb->idl, &nbrec_logical_router_col_name);
+    struct ovsdb_idl_index *nbrec_lrp_by_name
+        = ovsdb_idl_index_create1(nb->idl,
+                                  &nbrec_logical_router_port_col_name);
+    struct ovsdb_idl_index *nbrec_port_by_name
+        = ovsdb_idl_index_create1(nb->idl,
+                                  &nbrec_logical_switch_port_col_name);
+    struct ovsdb_idl_index *sbrec_chassis_by_name
+        = ovsdb_idl_index_create1(sb->idl, &sbrec_chassis_col_name);
+    struct ovsdb_idl_index *sbrec_port_binding_by_name
+        = ovsdb_idl_index_create1(sb->idl,
+                                  &sbrec_port_binding_col_logical_port);
+    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type
+        = ovsdb_idl_index_create1(sb->idl,
+                                  &sbrec_service_monitor_col_remote);
+    struct ovsdb_idl_index *sbrec_service_monitor_by_ic_learned
+        = ovsdb_idl_index_create1(sb->idl,
+                                  &sbrec_service_monitor_col_ic_learned);
+    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type_logical_port
+        = ovsdb_idl_index_create2(sb->idl,
+                                  &sbrec_service_monitor_col_remote,
+                                  &sbrec_service_monitor_col_logical_port);
+    struct ovsdb_idl_index *icnbrec_transit_switch_by_name
+        = ovsdb_idl_index_create1(icnb->idl,
+                                  &icnbrec_transit_switch_col_name);
+    struct ovsdb_idl_index *icsbrec_port_binding_by_az
+        = ovsdb_idl_index_create1(icsb->idl,
+                                  &icsbrec_port_binding_col_availability_zone);
+    struct ovsdb_idl_index *icsbrec_port_binding_by_ts
+        = ovsdb_idl_index_create1(icsb->idl,
+                                  &icsbrec_port_binding_col_transit_switch);
+    struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az
+        = ovsdb_idl_index_create2(icsb->idl,
+                                  &icsbrec_port_binding_col_transit_switch,
+                                  &icsbrec_port_binding_col_availability_zone);
+    struct ovsdb_idl_index *icsbrec_route_by_az
+        = ovsdb_idl_index_create1(icsb->idl,
+                                  &icsbrec_route_col_availability_zone);
+    struct ovsdb_idl_index *icsbrec_route_by_ts
+        = ovsdb_idl_index_create1(icsb->idl,
+                                  &icsbrec_route_col_transit_switch);
+    struct ovsdb_idl_index *icsbrec_route_by_ts_az
+        = ovsdb_idl_index_create2(icsb->idl,
+                                  &icsbrec_route_col_transit_switch,
+                                  &icsbrec_route_col_availability_zone);
+    struct ovsdb_idl_index *icsbrec_service_monitor_by_source_az
+        = ovsdb_idl_index_create1(icsb->idl,
+            &icsbrec_service_monitor_col_source_availability_zone);
+    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az
+        = ovsdb_idl_index_create1(icsb->idl,
+            &icsbrec_service_monitor_col_target_availability_zone);
+    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az_logical_port
+        = ovsdb_idl_index_create2(icsb->idl,
+            &icsbrec_service_monitor_col_target_availability_zone,
+            &icsbrec_service_monitor_col_logical_port);
+
     engine_init(&en_ic, &engine_arg);
+
+    /* indexes */
+    engine_ovsdb_node_add_index(&en_nb_logical_switch,
+                                "nbrec_ls_by_name",
+                                nbrec_ls_by_name);
+    engine_ovsdb_node_add_index(&en_nb_logical_router,
+                                "nbrec_lr_by_name",
+                                nbrec_lr_by_name);
+    engine_ovsdb_node_add_index(&en_nb_logical_router,
+                                "nbrec_lrp_by_name",
+                                nbrec_lrp_by_name);
+    engine_ovsdb_node_add_index(&en_nb_logical_switch,
+                                "nbrec_port_by_name",
+                                nbrec_port_by_name);
+    engine_ovsdb_node_add_index(&en_sb_chassis,
+                                "sbrec_chassis_by_name",
+                                sbrec_chassis_by_name);
+    engine_ovsdb_node_add_index(&en_sb_port_binding,
+                                "sbrec_port_binding_by_name",
+                                sbrec_port_binding_by_name);
+    engine_ovsdb_node_add_index(&en_sb_service_monitor,
+                                "sbrec_service_monitor_by_remote_type",
+                                sbrec_service_monitor_by_remote_type);
+    engine_ovsdb_node_add_index(&en_sb_service_monitor,
+                                "sbrec_service_monitor_by_ic_learned",
+                                sbrec_service_monitor_by_ic_learned);
+    engine_ovsdb_node_add_index(&en_sb_service_monitor,
+        "sbrec_service_monitor_by_remote_type_logical_port",
+        sbrec_service_monitor_by_remote_type_logical_port);
+    engine_ovsdb_node_add_index(&en_icnb_transit_switch,
+                                "icnbrec_transit_switch_by_name",
+                                icnbrec_transit_switch_by_name);
+    engine_ovsdb_node_add_index(&en_icsb_port_binding,
+                                "icsbrec_port_binding_by_az",
+                                icsbrec_port_binding_by_az);
+    engine_ovsdb_node_add_index(&en_icsb_port_binding,
+                                "icsbrec_port_binding_by_ts",
+                                icsbrec_port_binding_by_ts);
+    engine_ovsdb_node_add_index(&en_icsb_port_binding,
+                                "icsbrec_port_binding_by_ts_az",
+                                icsbrec_port_binding_by_ts_az);
+    engine_ovsdb_node_add_index(&en_icsb_route,
+                                "icsbrec_route_by_az",
+                                icsbrec_route_by_az);
+    engine_ovsdb_node_add_index(&en_icsb_route,
+                                "icsbrec_route_by_ts",
+                                icsbrec_route_by_ts);
+    engine_ovsdb_node_add_index(&en_icsb_route,
+                                "icsbrec_route_by_ts_az",
+                                icsbrec_route_by_ts_az);
+    engine_ovsdb_node_add_index(&en_icsb_service_monitor,
+                                "icsbrec_service_monitor_by_source_az",
+                                icsbrec_service_monitor_by_source_az);
+    engine_ovsdb_node_add_index(&en_icsb_service_monitor,
+                                "icsbrec_service_monitor_by_target_az",
+                                icsbrec_service_monitor_by_target_az);
+    engine_ovsdb_node_add_index(&en_icsb_service_monitor,
+        "icsbrec_service_monitor_by_target_az_logical_port",
+        icsbrec_service_monitor_by_target_az_logical_port);
 }
 
 /* Returns true if the incremental processing ended up updating nodes. */
 bool
-inc_proc_ic_run(struct ic_context *ctx,
-                struct ic_engine_context *ic_eng_ctx)
+inc_proc_ic_run(struct ovsdb_idl_txn *ovnnb_txn,
+                struct ovsdb_idl_txn *ovnsb_txn,
+                struct ovsdb_idl_txn *ovninb_txn,
+                struct ovsdb_idl_txn *ovnisb_txn,
+                struct ic_engine_context *ctx,
+                const struct icsbrec_availability_zone *runned_az)
 {
-    ovs_assert(ctx->ovnnb_txn && ctx->ovnsb_txn &&
-               ctx->ovninb_txn && ctx->ovnisb_txn);
+    ovs_assert(ovnnb_txn && ovnsb_txn &&
+               ovninb_txn && ovnisb_txn);
 
     int64_t start = time_msec();
     engine_init_run();
 
     struct engine_context eng_ctx = {
-        .client_ctx = ctx,
+        .client_ctx = (void *) runned_az,
+        .ovnnb_idl_txn = ovnnb_txn,
+        .ovnsb_idl_txn = ovnsb_txn,
+        .ovninb_idl_txn = ovninb_txn,
+        .ovnisb_idl_txn = ovnisb_txn,
     };
 
     engine_set_context(&eng_ctx);
@@ -241,7 +368,7 @@ inc_proc_ic_run(struct ic_context *ctx,
     int64_t now = time_msec();
     /* Postpone the next run by length of current run with maximum capped
      * by "northd-backoff-interval-ms" interval. */
-    ic_eng_ctx->next_run_ms = now + MIN(now - start, ic_eng_ctx->backoff_ms);
+    ctx->next_run_ms = now + MIN(now - start, ctx->backoff_ms);
 
     return engine_has_updated();
 }
diff --git a/ic/inc-proc-ic.h b/ic/inc-proc-ic.h
index 9af147fb3..c50c1b02e 100644
--- a/ic/inc-proc-ic.h
+++ b/ic/inc-proc-ic.h
@@ -21,8 +21,12 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,
                       struct ovsdb_idl_loop *icnb,
                       struct ovsdb_idl_loop *icsb);
 
-bool inc_proc_ic_run(struct ic_context *ctx,
-                     struct ic_engine_context *ic_eng_ctx);
+bool inc_proc_ic_run(struct ovsdb_idl_txn *ovnnb_txn,
+                     struct ovsdb_idl_txn *ovnsb_txn,
+                     struct ovsdb_idl_txn *ovninb_txn,
+                     struct ovsdb_idl_txn *ovnisb_txn,
+                     struct ic_engine_context *ctx,
+                     const struct icsbrec_availability_zone *runned_az);
 
 void inc_proc_ic_cleanup(void);
 bool inc_proc_ic_can_run(struct ic_engine_context *ctx);
diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
index 41596d73a..f4a97fbca 100644
--- a/ic/ovn-ic.c
+++ b/ic/ovn-ic.c
@@ -48,6 +48,8 @@
 #include "vec.h"
 #include "inc-proc-ic.h"
 #include "ovn-ic.h"
+#include "stopwatch-names.h"
+#include "stopwatch.h"
 
 VLOG_DEFINE_THIS_MODULE(ovn_ic);
 
@@ -99,11 +101,13 @@ Options:\n\
     stream_usage("database", true, true, false);
 }
 
-static const struct icsbrec_availability_zone *
-az_run(struct ic_context *ctx)
+const struct icsbrec_availability_zone *
+az_run(struct ovsdb_idl *ovnnb_idl,
+       struct ovsdb_idl *ovnisb_idl,
+       struct ovsdb_idl_txn *ovnisb_idl_txn)
 {
     const struct nbrec_nb_global *nb_global =
-        nbrec_nb_global_first(ctx->ovnnb_idl);
+        nbrec_nb_global_first(ovnnb_idl);
 
     if (!nb_global) {
         VLOG_INFO("NB Global not exist.");
@@ -115,8 +119,8 @@ az_run(struct ic_context *ctx)
      * "ovn-ic-sbctl destroy avail <az>". */
     static char *az_name;
     const struct icsbrec_availability_zone *az;
-    if (ctx->ovnisb_txn && az_name && strcmp(az_name, nb_global->name)) {
-        ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_idl) {
+    if (ovnisb_idl_txn && az_name && strcmp(az_name, nb_global->name)) {
+        ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ovnisb_idl) {
             /* AZ name update locally need to update az in ISB. */
             if (nb_global->name[0] && !strcmp(az->name, az_name)) {
                 icsbrec_availability_zone_set_name(az, nb_global->name);
@@ -138,24 +142,22 @@ az_run(struct ic_context *ctx)
         az_name = xstrdup(nb_global->name);
     }
 
-    if (ctx->ovnisb_txn) {
-        ovsdb_idl_txn_add_comment(ctx->ovnisb_txn, "AZ %s", az_name);
+    if (ovnisb_idl_txn) {
+        ovsdb_idl_txn_add_comment(ovnisb_idl_txn, "AZ %s", az_name);
     }
 
-    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ctx->ovnisb_idl) {
+    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (az, ovnisb_idl) {
         if (!strcmp(az->name, az_name)) {
-            ctx->runned_az = az;
-            return az;
+            return (struct icsbrec_availability_zone *) az;
         }
     }
 
     /* Create AZ in ISB */
-    if (ctx->ovnisb_txn) {
+    if (ovnisb_idl_txn) {
         VLOG_INFO("Register AZ %s to interconnection DB.", az_name);
-        az = icsbrec_availability_zone_insert(ctx->ovnisb_txn);
+        az = icsbrec_availability_zone_insert(ovnisb_idl_txn);
         icsbrec_availability_zone_set_name(az, az_name);
-        ctx->runned_az = az;
-        return az;
+        return (struct icsbrec_availability_zone *) az;
     }
     return NULL;
 }
@@ -191,11 +193,14 @@ ic_pb_get_type(const struct icsbrec_port_binding *isb_pb)
 }
 
 static void
-enumerate_datapaths(struct ic_context *ctx, struct hmap *dp_tnlids,
-                    struct shash *isb_ts_dps, struct shash *isb_tr_dps)
+enumerate_datapaths(struct ic_input *ic,
+                    struct hmap *dp_tnlids,
+                    struct shash *isb_ts_dps,
+                    struct shash *isb_tr_dps)
 {
     const struct icsbrec_datapath_binding *isb_dp;
-    ICSBREC_DATAPATH_BINDING_FOR_EACH (isb_dp, ctx->ovnisb_idl) {
+    ICSBREC_DATAPATH_BINDING_TABLE_FOR_EACH (isb_dp,
+        ic->icsbrec_datapath_binding_table) {
         ovn_add_tnlid(dp_tnlids, isb_dp->tunnel_key);
 
         enum ic_datapath_type dp_type = ic_dp_get_type(isb_dp);
@@ -210,18 +215,20 @@ enumerate_datapaths(struct ic_context *ctx, struct hmap 
*dp_tnlids,
 }
 
 static void
-ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,
+ts_run(struct engine_context *ctx,
+       struct ic_input *ic,
+       struct hmap *dp_tnlids,
        struct shash *isb_ts_dps)
 {
     const struct icnbrec_transit_switch *ts;
     bool dp_key_refresh = false;
     bool vxlan_mode = false;
     const struct icnbrec_ic_nb_global *ic_nb =
-        icnbrec_ic_nb_global_first(ctx->ovninb_idl);
+        icnbrec_ic_nb_global_table_first(ic->icnbrec_ic_nb_global_table);
 
     if (ic_nb && smap_get_bool(&ic_nb->options, "vxlan_mode", false)) {
         const struct icsbrec_encap *encap;
-        ICSBREC_ENCAP_FOR_EACH (encap, ctx->ovnisb_idl) {
+        ICSBREC_ENCAP_TABLE_FOR_EACH (encap, ic->icsbrec_encap_table) {
             if (!strcmp(encap->type, "vxlan")) {
                 vxlan_mode = true;
                 break;
@@ -230,12 +237,13 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,
     }
 
     /* Sync INB TS to AZ NB */
-    if (ctx->ovnnb_txn) {
+    if (ctx->ovnnb_idl_txn) {
         struct shash nb_tses = SHASH_INITIALIZER(&nb_tses);
         const struct nbrec_logical_switch *ls;
 
         /* Get current NB Logical_Switch with other_config:interconn-ts */
-        NBREC_LOGICAL_SWITCH_FOR_EACH (ls, ctx->ovnnb_idl) {
+        NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH (ls,
+                                             ic->nbrec_logical_switch_table) {
             const char *ts_name = smap_get(&ls->other_config, "interconn-ts");
             if (ts_name) {
                 shash_add(&nb_tses, ts_name, ls);
@@ -243,10 +251,11 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,
         }
 
         /* Create/update NB Logical_Switch for each TS */
-        ICNBREC_TRANSIT_SWITCH_FOR_EACH (ts, ctx->ovninb_idl) {
+        ICNBREC_TRANSIT_SWITCH_TABLE_FOR_EACH (ts,
+            ic->icnbrec_transit_switch_table) {
             ls = shash_find_and_delete(&nb_tses, ts->name);
             if (!ls) {
-                ls = nbrec_logical_switch_insert(ctx->ovnnb_txn);
+                ls = nbrec_logical_switch_insert(ctx->ovnnb_idl_txn);
                 nbrec_logical_switch_set_name(ls, ts->name);
                 nbrec_logical_switch_update_other_config_setkey(ls,
                                                                 "interconn-ts",
@@ -294,9 +303,10 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,
     /* Sync TS between INB and ISB.  This is performed after syncing with AZ
      * SB, to avoid uncommitted ISB datapath tunnel key to be synced back to
      * AZ. */
-    if (ctx->ovnisb_txn) {
+    if (ctx->ovnisb_idl_txn) {
         /* Create ISB Datapath_Binding */
-        ICNBREC_TRANSIT_SWITCH_FOR_EACH (ts, ctx->ovninb_idl) {
+        ICNBREC_TRANSIT_SWITCH_TABLE_FOR_EACH (ts,
+            ic->icnbrec_transit_switch_table) {
             const struct icsbrec_datapath_binding *isb_dp =
                 shash_find_and_delete(isb_ts_dps, ts->name);
             if (!isb_dp) {
@@ -307,7 +317,7 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,
                     continue;
                 }
 
-                isb_dp = icsbrec_datapath_binding_insert(ctx->ovnisb_txn);
+                isb_dp = icsbrec_datapath_binding_insert(ctx->ovnisb_idl_txn);
                 icsbrec_datapath_binding_set_transit_switch(isb_dp, ts->name);
                 icsbrec_datapath_binding_set_tunnel_key(isb_dp, dp_key);
             } else if (dp_key_refresh) {
@@ -337,14 +347,17 @@ ts_run(struct ic_context *ctx, struct hmap *dp_tnlids,
 }
 
 static void
-tr_run(struct ic_context *ctx, struct hmap *dp_tnlids,
+tr_run(struct engine_context *ctx,
+       struct ic_input *ic,
+       struct hmap *dp_tnlids,
        struct shash *isb_tr_dps)
 {
     const struct nbrec_logical_router *lr;
 
-    if (ctx->ovnnb_txn) {
+    if (ctx->ovnnb_idl_txn) {
         struct shash nb_tres = SHASH_INITIALIZER(&nb_tres);
-        NBREC_LOGICAL_ROUTER_FOR_EACH (lr, ctx->ovnnb_idl) {
+        NBREC_LOGICAL_ROUTER_TABLE_FOR_EACH (lr,
+                                             ic->nbrec_logical_router_table) {
             const char *tr_name = smap_get(&lr->options, "interconn-tr");
             if (tr_name) {
                 shash_add(&nb_tres, tr_name, lr);
@@ -352,10 +365,11 @@ tr_run(struct ic_context *ctx, struct hmap *dp_tnlids,
         }
 
         const struct icnbrec_transit_router *tr;
-        ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->ovninb_idl) {
+        ICNBREC_TRANSIT_ROUTER_TABLE_FOR_EACH (tr,
+            ic->icnbrec_transit_router_table) {
             lr = shash_find_and_delete(&nb_tres, tr->name);
             if (!lr) {
-                lr = nbrec_logical_router_insert(ctx->ovnnb_txn);
+                lr = nbrec_logical_router_insert(ctx->ovnnb_idl_txn);
                 nbrec_logical_router_set_name(lr, tr->name);
                 nbrec_logical_router_update_options_setkey(
                     lr, "interconn-tr", tr->name);
@@ -383,10 +397,11 @@ tr_run(struct ic_context *ctx, struct hmap *dp_tnlids,
     /* Sync TR between INB and ISB.  This is performed after syncing with AZ
      * SB, to avoid uncommitted ISB datapath tunnel key to be synced back to
      * AZ. */
-    if (ctx->ovnisb_txn) {
+    if (ctx->ovnisb_idl_txn) {
         /* Create ISB Datapath_Binding */
         const struct icnbrec_transit_router *tr;
-        ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->ovninb_idl) {
+        ICNBREC_TRANSIT_ROUTER_TABLE_FOR_EACH (tr,
+            ic->icnbrec_transit_router_table) {
             char *uuid_str = uuid_to_string(&tr->header_.uuid);
             struct icsbrec_datapath_binding *isb_dp =
                 shash_find_and_delete(isb_tr_dps, uuid_str);
@@ -399,7 +414,7 @@ tr_run(struct ic_context *ctx, struct hmap *dp_tnlids,
                     continue;
                 }
 
-                isb_dp = icsbrec_datapath_binding_insert(ctx->ovnisb_txn);
+                isb_dp = icsbrec_datapath_binding_insert(ctx->ovnisb_idl_txn);
                 icsbrec_datapath_binding_set_tunnel_key(isb_dp, dp_key);
                 icsbrec_datapath_binding_set_nb_ic_uuid(isb_dp,
                                                         &tr->header_.uuid, 1);
@@ -451,7 +466,7 @@ is_gateway_data_changed(const struct icsbrec_gateway *gw,
 }
 
 static void
-sync_isb_gw_to_sb(struct ic_context *ctx,
+sync_isb_gw_to_sb(struct engine_context *ctx,
                   const struct icsbrec_gateway *gw,
                   const struct sbrec_chassis *chassis)
 {
@@ -464,7 +479,7 @@ sync_isb_gw_to_sb(struct ic_context *ctx,
     struct sbrec_encap **sb_encaps =
         xmalloc(gw->n_encaps * sizeof *sb_encaps);
     for (int i = 0; i < gw->n_encaps; i++) {
-        sb_encap = sbrec_encap_insert(ctx->ovnsb_txn);
+        sb_encap = sbrec_encap_insert(ctx->ovnsb_idl_txn);
         sbrec_encap_set_chassis_name(sb_encap, gw->name);
         sbrec_encap_set_ip(sb_encap, gw->encaps[i]->ip);
         sbrec_encap_set_type(sb_encap, gw->encaps[i]->type);
@@ -476,7 +491,7 @@ sync_isb_gw_to_sb(struct ic_context *ctx,
 }
 
 static void
-sync_sb_gw_to_isb(struct ic_context *ctx,
+sync_sb_gw_to_isb(struct engine_context *ctx,
                   const struct sbrec_chassis *chassis,
                   const struct icsbrec_gateway *gw)
 {
@@ -488,7 +503,7 @@ sync_sb_gw_to_isb(struct ic_context *ctx,
     struct icsbrec_encap **isb_encaps =
         xmalloc(chassis->n_encaps * sizeof *isb_encaps);
     for (int i = 0; i < chassis->n_encaps; i++) {
-        isb_encap = icsbrec_encap_insert(ctx->ovnisb_txn);
+        isb_encap = icsbrec_encap_insert(ctx->ovnisb_idl_txn);
         icsbrec_encap_set_gateway_name(isb_encap,
                                       chassis->name);
         icsbrec_encap_set_ip(isb_encap, chassis->encaps[i]->ip);
@@ -504,17 +519,18 @@ sync_sb_gw_to_isb(struct ic_context *ctx,
 }
 
 static void
-gateway_run(struct ic_context *ctx)
+gateway_run(struct engine_context *ctx,
+            struct ic_input *ic)
 {
-    if (!ctx->ovnisb_txn || !ctx->ovnsb_txn) {
+    if (!ctx->ovnisb_idl_txn || !ctx->ovnsb_idl_txn) {
         return;
     }
 
     struct shash local_gws = SHASH_INITIALIZER(&local_gws);
     struct shash remote_gws = SHASH_INITIALIZER(&remote_gws);
     const struct icsbrec_gateway *gw;
-    ICSBREC_GATEWAY_FOR_EACH (gw, ctx->ovnisb_idl) {
-        if (gw->availability_zone == ctx->runned_az) {
+    ICSBREC_GATEWAY_TABLE_FOR_EACH (gw, ic->icsbrec_gateway_table) {
+        if (gw->availability_zone == ic->runned_az) {
             shash_add(&local_gws, gw->name, gw);
         } else {
             shash_add(&remote_gws, gw->name, gw);
@@ -522,12 +538,12 @@ gateway_run(struct ic_context *ctx)
     }
 
     const struct sbrec_chassis *chassis;
-    SBREC_CHASSIS_FOR_EACH (chassis, ctx->ovnsb_idl) {
+    SBREC_CHASSIS_TABLE_FOR_EACH (chassis, ic->sbrec_chassis_table) {
         if (smap_get_bool(&chassis->other_config, "is-interconn", false)) {
             gw = shash_find_and_delete(&local_gws, chassis->name);
             if (!gw) {
-                gw = icsbrec_gateway_insert(ctx->ovnisb_txn);
-                icsbrec_gateway_set_availability_zone(gw, ctx->runned_az);
+                gw = icsbrec_gateway_insert(ctx->ovnisb_idl_txn);
+                icsbrec_gateway_set_availability_zone(gw, ic->runned_az);
                 icsbrec_gateway_set_name(gw, chassis->name);
                 sync_sb_gw_to_isb(ctx, chassis, gw);
             } else if (is_gateway_data_changed(gw, chassis)) {
@@ -553,7 +569,7 @@ gateway_run(struct ic_context *ctx)
     /* Create SB chassis for remote gateways in ISB */
     SHASH_FOR_EACH (node, &remote_gws) {
         gw = node->data;
-        chassis = sbrec_chassis_insert(ctx->ovnsb_txn);
+        chassis = sbrec_chassis_insert(ctx->ovnsb_idl_txn);
         sbrec_chassis_set_name(chassis, gw->name);
         sync_isb_gw_to_sb(ctx, gw, chassis);
     }
@@ -561,15 +577,15 @@ gateway_run(struct ic_context *ctx)
 }
 
 static const struct nbrec_logical_switch *
-find_ts_in_nb(struct ic_context *ctx, char *ts_name)
+find_ts_in_nb(struct ic_input *ic, char *ts_name)
 {
     const struct nbrec_logical_switch *key =
-        nbrec_logical_switch_index_init_row(ctx->nbrec_ls_by_name);
+        nbrec_logical_switch_index_init_row(ic->nbrec_ls_by_name);
     nbrec_logical_switch_index_set_name(key, ts_name);
 
     const struct nbrec_logical_switch *ls;
     bool found = false;
-    NBREC_LOGICAL_SWITCH_FOR_EACH_EQUAL (ls, key, ctx->nbrec_ls_by_name) {
+    NBREC_LOGICAL_SWITCH_FOR_EACH_EQUAL (ls, key, ic->nbrec_ls_by_name) {
         const char *ls_ts_name = smap_get(&ls->other_config, "interconn-ts");
         if (ls_ts_name && !strcmp(ts_name, ls_ts_name)) {
             found = true;
@@ -585,15 +601,15 @@ find_ts_in_nb(struct ic_context *ctx, char *ts_name)
 }
 
 static const struct nbrec_logical_router *
-find_tr_in_nb(struct ic_context *ctx, char *tr_name)
+find_tr_in_nb(struct ic_input *ic, char *tr_name)
 {
     const struct nbrec_logical_router *key =
-        nbrec_logical_router_index_init_row(ctx->nbrec_lr_by_name);
+        nbrec_logical_router_index_init_row(ic->nbrec_lr_by_name);
     nbrec_logical_router_index_set_name(key, tr_name);
 
     const struct nbrec_logical_router *lr;
     bool found = false;
-    NBREC_LOGICAL_ROUTER_FOR_EACH_EQUAL (lr, key, ctx->nbrec_lr_by_name) {
+    NBREC_LOGICAL_ROUTER_FOR_EACH_EQUAL (lr, key, ic->nbrec_lr_by_name) {
         if (smap_get(&lr->options, "interconn-tr")) {
             found = true;
             break;
@@ -624,7 +640,7 @@ find_sb_pb_by_name(struct ovsdb_idl_index 
*sbrec_port_binding_by_name,
 }
 
 static const struct sbrec_port_binding *
-find_peer_port(struct ic_context *ctx,
+find_peer_port(struct ic_input *ic,
                const struct sbrec_port_binding *sb_pb)
 {
     const char *peer_name = smap_get(&sb_pb->options, "peer");
@@ -632,61 +648,61 @@ find_peer_port(struct ic_context *ctx,
         return NULL;
     }
 
-    return find_sb_pb_by_name(ctx->sbrec_port_binding_by_name, peer_name);
+    return find_sb_pb_by_name(ic->sbrec_port_binding_by_name, peer_name);
 }
 
 static const struct sbrec_port_binding *
-find_crp_from_lrp(struct ic_context *ctx,
+find_crp_from_lrp(struct ic_input *ic,
                   const struct sbrec_port_binding *lrp_pb)
 {
     char *crp_name = ovn_chassis_redirect_name(lrp_pb->logical_port);
 
     const struct sbrec_port_binding *pb =
-        find_sb_pb_by_name(ctx->sbrec_port_binding_by_name, crp_name);
+        find_sb_pb_by_name(ic->sbrec_port_binding_by_name, crp_name);
 
     free(crp_name);
     return pb;
 }
 
 static const struct sbrec_port_binding *
-find_crp_for_sb_pb(struct ic_context *ctx,
+find_crp_for_sb_pb(struct ic_input *ic,
                    const struct sbrec_port_binding *sb_pb)
 {
-    const struct sbrec_port_binding *peer = find_peer_port(ctx, sb_pb);
+    const struct sbrec_port_binding *peer = find_peer_port(ic, sb_pb);
     if (!peer) {
         return NULL;
     }
 
-    return find_crp_from_lrp(ctx, peer);
+    return find_crp_from_lrp(ic, peer);
 }
 
 static const struct nbrec_logical_switch_port *
-get_lsp_by_ts_port_name(struct ic_context *ctx, const char *ts_port_name)
+get_lsp_by_ts_port_name(struct ic_input *ic, const char *ts_port_name)
 {
     const struct nbrec_logical_switch_port *lsp, *key;
 
-    key = nbrec_logical_switch_port_index_init_row(ctx->nbrec_port_by_name);
+    key = nbrec_logical_switch_port_index_init_row(ic->nbrec_port_by_name);
     nbrec_logical_switch_port_index_set_name(key, ts_port_name);
-    lsp = nbrec_logical_switch_port_index_find(ctx->nbrec_port_by_name, key);
+    lsp = nbrec_logical_switch_port_index_find(ic->nbrec_port_by_name, key);
     nbrec_logical_switch_port_index_destroy_row(key);
 
     return lsp;
 }
 
 static const char *
-get_lp_address_for_sb_pb(struct ic_context *ctx,
+get_lp_address_for_sb_pb(struct ic_input *ic,
                          const struct sbrec_port_binding *sb_pb)
 {
     const struct nbrec_logical_switch_port *nb_lsp;
 
-    nb_lsp = get_lsp_by_ts_port_name(ctx, sb_pb->logical_port);
+    nb_lsp = get_lsp_by_ts_port_name(ic, sb_pb->logical_port);
     if (!strcmp(nb_lsp->type, "switch")) {
         /* Switches always have implicit "unknown" address, and IC-SB port
          * binding can only have one address specified. */
         return "unknown";
     }
 
-    const struct sbrec_port_binding *peer = find_peer_port(ctx, sb_pb);
+    const struct sbrec_port_binding *peer = find_peer_port(ic, sb_pb);
     if (!peer) {
         return NULL;
     }
@@ -695,14 +711,14 @@ get_lp_address_for_sb_pb(struct ic_context *ctx,
 }
 
 static const struct sbrec_chassis *
-find_sb_chassis(struct ic_context *ctx, const char *name)
+find_sb_chassis(struct ic_input *ic, const char *name)
 {
     const struct sbrec_chassis *key =
-        sbrec_chassis_index_init_row(ctx->sbrec_chassis_by_name);
+        sbrec_chassis_index_init_row(ic->sbrec_chassis_by_name);
     sbrec_chassis_index_set_name(key, name);
 
     const struct sbrec_chassis *chassis =
-        sbrec_chassis_index_find(ctx->sbrec_chassis_by_name, key);
+        sbrec_chassis_index_find(ic->sbrec_chassis_by_name, key);
     sbrec_chassis_index_destroy_row(key);
 
     return chassis;
@@ -741,11 +757,11 @@ sync_lrp_tnl_key(const struct nbrec_logical_router_port 
*lrp,
 }
 
 static bool
-get_router_uuid_by_sb_pb(struct ic_context *ctx,
+get_router_uuid_by_sb_pb(struct ic_input *ic,
                          const struct sbrec_port_binding *sb_pb,
                          struct uuid *router_uuid)
 {
-    const struct sbrec_port_binding *router_pb = find_peer_port(ctx, sb_pb);
+    const struct sbrec_port_binding *router_pb = find_peer_port(ic, sb_pb);
     if (!router_pb || !router_pb->datapath) {
         return NULL;
     }
@@ -754,12 +770,12 @@ get_router_uuid_by_sb_pb(struct ic_context *ctx,
 }
 
 static void
-update_isb_pb_external_ids(struct ic_context *ctx,
+update_isb_pb_external_ids(struct ic_input *ic,
                            const struct sbrec_port_binding *sb_pb,
                            const struct icsbrec_port_binding *isb_pb)
 {
     struct uuid lr_uuid;
-    if (!get_router_uuid_by_sb_pb(ctx, sb_pb, &lr_uuid)) {
+    if (!get_router_uuid_by_sb_pb(ic, sb_pb, &lr_uuid)) {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
         VLOG_WARN_RL(&rl, "Can't get router uuid for transit switch port %s.",
                      isb_pb->logical_port);
@@ -784,13 +800,13 @@ update_isb_pb_external_ids(struct ic_context *ctx,
  *   - Sync tunnel key from ISB to NB.
  */
 static void
-sync_local_port(struct ic_context *ctx,
+sync_local_port(struct ic_input *ic,
                 const struct icsbrec_port_binding *isb_pb,
                 const struct sbrec_port_binding *sb_pb,
                 const struct nbrec_logical_switch_port *lsp)
 {
     /* Sync address from NB to ISB */
-    const char *address = get_lp_address_for_sb_pb(ctx, sb_pb);
+    const char *address = get_lp_address_for_sb_pb(ic, sb_pb);
     if (!address) {
         VLOG_DBG("Can't get router/switch port address for logical"
                  " switch port %s", sb_pb->logical_port);
@@ -804,7 +820,7 @@ sync_local_port(struct ic_context *ctx,
     }
 
     /* Sync gateway from SB to ISB */
-    const struct sbrec_port_binding *crp = find_crp_for_sb_pb(ctx, sb_pb);
+    const struct sbrec_port_binding *crp = find_crp_for_sb_pb(ic, sb_pb);
     if (crp && crp->chassis) {
         if (strcmp(crp->chassis->name, isb_pb->gateway)) {
             icsbrec_port_binding_set_gateway(isb_pb, crp->chassis->name);
@@ -820,7 +836,7 @@ sync_local_port(struct ic_context *ctx,
     }
 
     /* Sync external_ids:router-id to ISB */
-    update_isb_pb_external_ids(ctx, sb_pb, isb_pb);
+    update_isb_pb_external_ids(ic, sb_pb, isb_pb);
 
     /* Sync back tunnel key from ISB to NB */
     sync_lsp_tnl_key(lsp, isb_pb->tunnel_key);
@@ -831,7 +847,7 @@ sync_local_port(struct ic_context *ctx,
  *   - Sync gateway from ISB to SB
  */
 static void
-sync_remote_port(struct ic_context *ctx,
+sync_remote_port(struct ic_input *ic,
                  const struct icsbrec_port_binding *isb_pb,
                  const struct nbrec_logical_switch_port *lsp,
                  const struct sbrec_port_binding *sb_pb)
@@ -861,7 +877,7 @@ sync_remote_port(struct ic_context *ctx,
     if (isb_pb->gateway[0]) {
         if (!sb_pb->chassis || strcmp(sb_pb->chassis->name, isb_pb->gateway)) {
             const struct sbrec_chassis *chassis =
-                find_sb_chassis(ctx, isb_pb->gateway);
+                find_sb_chassis(ic, isb_pb->gateway);
             if (!chassis) {
                 VLOG_DBG("Chassis %s is not found in SB, syncing from ISB "
                          "to SB skipped for logical port %s.",
@@ -924,12 +940,12 @@ sync_router_port(const struct icsbrec_port_binding 
*isb_pb,
 }
 
 static void
-create_nb_lsp(struct ic_context *ctx,
+create_nb_lsp(struct engine_context *ctx,
               const struct icsbrec_port_binding *isb_pb,
               const struct nbrec_logical_switch *ls)
 {
     const struct nbrec_logical_switch_port *lsp =
-        nbrec_logical_switch_port_insert(ctx->ovnnb_txn);
+        nbrec_logical_switch_port_insert(ctx->ovnnb_idl_txn);
     nbrec_logical_switch_port_set_name(lsp, isb_pb->logical_port);
     nbrec_logical_switch_port_set_type(lsp, "remote");
 
@@ -953,7 +969,7 @@ allocate_port_key(struct hmap *pb_tnlids)
 }
 
 static const struct icsbrec_port_binding *
-create_isb_pb(struct ic_context *ctx, const char *logical_port,
+create_isb_pb(struct engine_context *ctx, const char *logical_port,
               const struct icsbrec_availability_zone *az, const char *ts_name,
               const struct uuid *nb_ic_uuid, const char *type,
               struct hmap *pb_tnlids)
@@ -964,7 +980,7 @@ create_isb_pb(struct ic_context *ctx, const char 
*logical_port,
     }
 
     const struct icsbrec_port_binding *isb_pb =
-        icsbrec_port_binding_insert(ctx->ovnisb_txn);
+        icsbrec_port_binding_insert(ctx->ovnisb_idl_txn);
     icsbrec_port_binding_set_availability_zone(isb_pb, az);
     icsbrec_port_binding_set_transit_switch(isb_pb, ts_name);
     icsbrec_port_binding_set_logical_port(isb_pb, logical_port);
@@ -975,25 +991,25 @@ create_isb_pb(struct ic_context *ctx, const char 
*logical_port,
 }
 
 static const struct nbrec_logical_router_port *
-get_lrp_by_lrp_name(struct ic_context *ctx, const char *lrp_name)
+get_lrp_by_lrp_name(struct ic_input *ic, const char *lrp_name)
 {
     const struct nbrec_logical_router_port *lrp;
     const struct nbrec_logical_router_port *lrp_key =
-        nbrec_logical_router_port_index_init_row(ctx->nbrec_lrp_by_name);
+        nbrec_logical_router_port_index_init_row(ic->nbrec_lrp_by_name);
     nbrec_logical_router_port_index_set_name(lrp_key, lrp_name);
     lrp =
-        nbrec_logical_router_port_index_find(ctx->nbrec_lrp_by_name, lrp_key);
+        nbrec_logical_router_port_index_find(ic->nbrec_lrp_by_name, lrp_key);
     nbrec_logical_router_port_index_destroy_row(lrp_key);
 
     return lrp;
 }
 
 static bool
-trp_is_remote(struct ic_context *ctx, const char *chassis_name)
+trp_is_remote(struct ic_input *ic, const char *chassis_name)
 {
     if (chassis_name) {
         const struct sbrec_chassis *chassis =
-            find_sb_chassis(ctx, chassis_name);
+            find_sb_chassis(ic, chassis_name);
         if (chassis) {
             return smap_get_bool(&chassis->other_config, "is-remote", false);
         } else {
@@ -1005,11 +1021,11 @@ trp_is_remote(struct ic_context *ctx, const char 
*chassis_name)
 }
 
 static struct nbrec_logical_router_port *
-lrp_create(struct ic_context *ctx, const struct nbrec_logical_router *lr,
+lrp_create(struct engine_context *ctx, const struct nbrec_logical_router *lr,
            const struct icnbrec_transit_router_port *trp)
 {
     struct nbrec_logical_router_port *lrp =
-        nbrec_logical_router_port_insert(ctx->ovnnb_txn);
+        nbrec_logical_router_port_insert(ctx->ovnnb_idl_txn);
     nbrec_logical_router_port_set_name(lrp, trp->name);
 
     nbrec_logical_router_port_update_options_setkey(lrp, "interconn-tr",
@@ -1019,20 +1035,20 @@ lrp_create(struct ic_context *ctx, const struct 
nbrec_logical_router *lr,
 }
 
 static void
-sync_ts_isb_pb(struct ic_context *ctx, const struct sbrec_port_binding *sb_pb,
+sync_ts_isb_pb(struct ic_input *ic, const struct sbrec_port_binding *sb_pb,
                const struct icsbrec_port_binding *isb_pb)
 {
-    const char *address = get_lp_address_for_sb_pb(ctx, sb_pb);
+    const char *address = get_lp_address_for_sb_pb(ic, sb_pb);
     if (address) {
         icsbrec_port_binding_set_address(isb_pb, address);
     }
 
-    const struct sbrec_port_binding *crp = find_crp_for_sb_pb(ctx, sb_pb);
+    const struct sbrec_port_binding *crp = find_crp_for_sb_pb(ic, sb_pb);
     if (crp && crp->chassis) {
         icsbrec_port_binding_set_gateway(isb_pb, crp->chassis->name);
     }
 
-    update_isb_pb_external_ids(ctx, sb_pb, isb_pb);
+    update_isb_pb_external_ids(ic, sb_pb, isb_pb);
 
     /* XXX: Sync encap so that multiple encaps can be used for the same
      * gateway.  However, it is not needed for now, since we don't yet
@@ -1043,16 +1059,18 @@ sync_ts_isb_pb(struct ic_context *ctx, const struct 
sbrec_port_binding *sb_pb,
 }
 
 static const struct sbrec_port_binding *
-find_lsp_in_sb(struct ic_context *ctx,
+find_lsp_in_sb(struct ic_input *ic,
                const struct nbrec_logical_switch_port *lsp)
 {
-    return find_sb_pb_by_name(ctx->sbrec_port_binding_by_name, lsp->name);
+    return find_sb_pb_by_name(ic->sbrec_port_binding_by_name, lsp->name);
 }
 
 static void
-port_binding_run(struct ic_context *ctx)
+port_binding_run(struct engine_context *ctx,
+                 struct ic_input *ic)
 {
-    if (!ctx->ovnisb_txn || !ctx->ovnnb_txn || !ctx->ovnsb_txn) {
+    if (!ctx->ovnisb_idl_txn || !ctx->ovnnb_idl_txn
+        || !ctx->ovnsb_idl_txn) {
         return;
     }
 
@@ -1065,12 +1083,12 @@ port_binding_run(struct ic_context *ctx)
 
     const struct icsbrec_port_binding *isb_pb;
     const struct icsbrec_port_binding *isb_pb_key =
-        icsbrec_port_binding_index_init_row(ctx->icsbrec_port_binding_by_az);
+        icsbrec_port_binding_index_init_row(ic->icsbrec_port_binding_by_az);
     icsbrec_port_binding_index_set_availability_zone(isb_pb_key,
-                                                     ctx->runned_az);
+                                                     ic->runned_az);
 
     ICSBREC_PORT_BINDING_FOR_EACH_EQUAL (isb_pb, isb_pb_key,
-                                         ctx->icsbrec_port_binding_by_az) {
+                                         ic->icsbrec_port_binding_by_az) {
         ic_pb_get_type(isb_pb) != IC_ROUTER_PORT
             ? shash_add(&switch_all_local_pbs, isb_pb->logical_port, isb_pb)
             : shash_add(&router_all_local_pbs, isb_pb->logical_port, isb_pb);
@@ -1081,8 +1099,9 @@ port_binding_run(struct ic_context *ctx)
 
     const struct sbrec_port_binding *sb_pb;
     const struct icnbrec_transit_switch *ts;
-    ICNBREC_TRANSIT_SWITCH_FOR_EACH (ts, ctx->ovninb_idl) {
-        const struct nbrec_logical_switch *ls = find_ts_in_nb(ctx, ts->name);
+    ICNBREC_TRANSIT_SWITCH_TABLE_FOR_EACH (ts,
+                                           ic->icnbrec_transit_switch_table) {
+        const struct nbrec_logical_switch *ls = find_ts_in_nb(ic, ts->name);
         if (!ls) {
             VLOG_DBG("Transit switch %s not found in NB.", ts->name);
             continue;
@@ -1091,12 +1110,12 @@ port_binding_run(struct ic_context *ctx)
         struct shash remote_pbs = SHASH_INITIALIZER(&remote_pbs);
 
         isb_pb_key = icsbrec_port_binding_index_init_row(
-            ctx->icsbrec_port_binding_by_ts);
+            ic->icsbrec_port_binding_by_ts);
         icsbrec_port_binding_index_set_transit_switch(isb_pb_key, ts->name);
 
         ICSBREC_PORT_BINDING_FOR_EACH_EQUAL (isb_pb, isb_pb_key,
-                                             ctx->icsbrec_port_binding_by_ts) {
-            if (isb_pb->availability_zone == ctx->runned_az) {
+                                             ic->icsbrec_port_binding_by_ts) {
+            if (isb_pb->availability_zone == ic->runned_az) {
                 shash_add(&local_pbs, isb_pb->logical_port, isb_pb);
                 shash_find_and_delete(&switch_all_local_pbs,
                                       isb_pb->logical_port);
@@ -1113,18 +1132,18 @@ port_binding_run(struct ic_context *ctx)
             if (!strcmp(lsp->type, "router")
                 || !strcmp(lsp->type, "switch")) {
                 /* The port is local. */
-                sb_pb = find_lsp_in_sb(ctx, lsp);
+                sb_pb = find_lsp_in_sb(ic, lsp);
                 if (!sb_pb) {
                     continue;
                 }
                 isb_pb = shash_find_and_delete(&local_pbs, lsp->name);
                 if (!isb_pb) {
                     isb_pb = create_isb_pb(
-                        ctx, sb_pb->logical_port, ctx->runned_az, ts->name,
+                        ctx, sb_pb->logical_port, ic->runned_az, ts->name,
                         &ts->header_.uuid, "transit-switch-port", &pb_tnlids);
-                    sync_ts_isb_pb(ctx, sb_pb, isb_pb);
+                    sync_ts_isb_pb(ic, sb_pb, isb_pb);
                 } else {
-                    sync_local_port(ctx, isb_pb, sb_pb, lsp);
+                    sync_local_port(ic, isb_pb, sb_pb, lsp);
                 }
 
                 if (isb_pb->type) {
@@ -1142,11 +1161,11 @@ port_binding_run(struct ic_context *ctx)
                 if (!isb_pb) {
                     nbrec_logical_switch_update_ports_delvalue(ls, lsp);
                 } else {
-                    sb_pb = find_lsp_in_sb(ctx, lsp);
+                    sb_pb = find_lsp_in_sb(ic, lsp);
                     if (!sb_pb) {
                         continue;
                     }
-                    sync_remote_port(ctx, isb_pb, lsp, sb_pb);
+                    sync_remote_port(ic, isb_pb, lsp, sb_pb);
                 }
             } else {
                 VLOG_DBG("Ignore lsp %s on ts %s with type %s.",
@@ -1174,8 +1193,9 @@ port_binding_run(struct ic_context *ctx)
     shash_destroy(&switch_all_local_pbs);
 
     const struct icnbrec_transit_router *tr;
-    ICNBREC_TRANSIT_ROUTER_FOR_EACH (tr, ctx->ovninb_idl) {
-        const struct nbrec_logical_router *lr = find_tr_in_nb(ctx, tr->name);
+    ICNBREC_TRANSIT_ROUTER_TABLE_FOR_EACH (tr,
+                                           ic->icnbrec_transit_router_table) {
+        const struct nbrec_logical_router *lr = find_tr_in_nb(ic, tr->name);
         if (!lr) {
             VLOG_DBG("Transit router %s not found in NB.", tr->name);
             continue;
@@ -1193,12 +1213,12 @@ port_binding_run(struct ic_context *ctx)
         }
 
         isb_pb_key = icsbrec_port_binding_index_init_row(
-            ctx->icsbrec_port_binding_by_ts);
+            ic->icsbrec_port_binding_by_ts);
         icsbrec_port_binding_index_set_transit_switch(isb_pb_key, tr->name);
 
         ICSBREC_PORT_BINDING_FOR_EACH_EQUAL (isb_pb, isb_pb_key,
-                                             ctx->icsbrec_port_binding_by_ts) {
-            if (isb_pb->availability_zone == ctx->runned_az) {
+                                             ic->icsbrec_port_binding_by_ts) {
+            if (isb_pb->availability_zone == ic->runned_az) {
                 shash_add(&local_pbs, isb_pb->logical_port, isb_pb);
                 shash_find_and_delete(&router_all_local_pbs,
                                       isb_pb->logical_port);
@@ -1211,12 +1231,12 @@ port_binding_run(struct ic_context *ctx)
         for (size_t i = 0; i < tr->n_ports; i++) {
             const struct icnbrec_transit_router_port *trp = tr->ports[i];
 
-            if (trp_is_remote(ctx, trp->chassis)) {
+            if (trp_is_remote(ic, trp->chassis)) {
                 isb_pb = shash_find_and_delete(&remote_pbs, trp->name);
             } else {
                 isb_pb = shash_find_and_delete(&local_pbs, trp->name);
                 if (!isb_pb) {
-                    isb_pb = create_isb_pb(ctx, trp->name, ctx->runned_az,
+                    isb_pb = create_isb_pb(ctx, trp->name, ic->runned_az,
                                            tr->name, &tr->header_.uuid,
                                            "transit-router-port", &pb_tnlids);
                     icsbrec_port_binding_set_address(isb_pb, trp->mac);
@@ -1548,8 +1568,8 @@ add_to_routes_ad(struct hmap *routes_ad, const struct 
in6_addr prefix,
 
     uint hash = ic_route_hash(&prefix, plen, &nexthop, origin, route_table);
 
-    if (!ic_route_find(routes_ad, &prefix, plen, &nexthop, origin, route_table,
-                       hash)) {
+    if (!ic_route_find(routes_ad, &prefix, plen, &nexthop, origin,
+                       route_table, hash)) {
         struct ic_route_info *ic_route = xzalloc(sizeof *ic_route);
         ic_route->prefix = prefix;
         ic_route->plen = plen;
@@ -1921,11 +1941,11 @@ route_need_learn(const struct nbrec_logical_router *lr,
 }
 
 static const char *
-get_lrp_name_by_ts_port_name(struct ic_context *ctx, const char *ts_port_name)
+get_lrp_name_by_ts_port_name(struct ic_input *ic, const char *ts_port_name)
 {
     const struct nbrec_logical_switch_port *nb_lsp;
 
-    nb_lsp = get_lsp_by_ts_port_name(ctx, ts_port_name);
+    nb_lsp = get_lsp_by_ts_port_name(ic, ts_port_name);
     if (!nb_lsp) {
         return NULL;
     }
@@ -1934,12 +1954,12 @@ get_lrp_name_by_ts_port_name(struct ic_context *ctx, 
const char *ts_port_name)
 }
 
 static const struct nbrec_logical_router_port *
-find_lrp_of_nexthop(struct ic_context *ctx,
+find_lrp_of_nexthop(struct ic_input *ic,
                     const struct icsbrec_route *isb_route)
 {
     const struct nbrec_logical_router_port *lrp;
     const struct nbrec_logical_switch *ls;
-    ls = find_ts_in_nb(ctx, isb_route->transit_switch);
+    ls = find_ts_in_nb(ic, isb_route->transit_switch);
     if (!ls) {
         return NULL;
     }
@@ -1951,13 +1971,13 @@ find_lrp_of_nexthop(struct ic_context *ctx,
 
     for (size_t i = 0; i < ls->n_ports; i++) {
         char *lsp_name = ls->ports[i]->name;
-        const char *lrp_name = get_lrp_name_by_ts_port_name(ctx,
+        const char *lrp_name = get_lrp_name_by_ts_port_name(ic,
                                                             lsp_name);
         if (!lrp_name) {
             continue;
         }
 
-        lrp = get_lrp_by_lrp_name(ctx, lrp_name);
+        lrp = get_lrp_by_lrp_name(ic, lrp_name);
         if (!lrp) {
             continue;
         }
@@ -1995,13 +2015,13 @@ find_lrp_of_nexthop(struct ic_context *ctx,
 }
 
 static bool
-lrp_is_ts_port(struct ic_context *ctx, struct ic_router_info *ic_lr,
+lrp_is_ts_port(struct ic_input *ic, struct ic_router_info *ic_lr,
                const char *lrp_name)
 {
     const struct icsbrec_port_binding *isb_pb;
     const char *ts_lrp_name;
     VECTOR_FOR_EACH (&ic_lr->isb_pbs, isb_pb) {
-        ts_lrp_name = get_lrp_name_by_ts_port_name(ctx, isb_pb->logical_port);
+        ts_lrp_name = get_lrp_name_by_ts_port_name(ic, isb_pb->logical_port);
         if (!strcmp(ts_lrp_name, lrp_name)) {
             return true;
         }
@@ -2010,14 +2030,15 @@ lrp_is_ts_port(struct ic_context *ctx, struct 
ic_router_info *ic_lr,
 }
 
 static void
-sync_learned_routes(struct ic_context *ctx,
+sync_learned_routes(struct engine_context *ctx,
+                    struct ic_input *ic,
                     struct ic_router_info *ic_lr)
 {
-    ovs_assert(ctx->ovnnb_txn);
+    ovs_assert(ctx->ovnnb_idl_txn);
     const struct icsbrec_route *isb_route, *isb_route_key;
 
     const struct nbrec_nb_global *nb_global =
-        nbrec_nb_global_first(ctx->ovnnb_idl);
+        nbrec_nb_global_table_first(ic->nbrec_nb_global_table);
     ovs_assert(nb_global);
 
     const char *lrp_name, *ts_route_table, *route_filter_tag;
@@ -2027,8 +2048,8 @@ sync_learned_routes(struct ic_context *ctx,
         if (!strcmp(isb_pb->address, "")) {
             continue;
         }
-        lrp_name = get_lrp_name_by_ts_port_name(ctx, isb_pb->logical_port);
-        lrp = get_lrp_by_lrp_name(ctx, lrp_name);
+        lrp_name = get_lrp_name_by_ts_port_name(ic, isb_pb->logical_port);
+        lrp = get_lrp_by_lrp_name(ic, lrp_name);
         if (lrp) {
             ts_route_table = smap_get_def(&lrp->options, "route_table", "");
             route_filter_tag = smap_get_def(&lrp->options,
@@ -2038,12 +2059,12 @@ sync_learned_routes(struct ic_context *ctx,
             route_filter_tag = "";
         }
 
-        isb_route_key = icsbrec_route_index_init_row(ctx->icsbrec_route_by_ts);
+        isb_route_key = icsbrec_route_index_init_row(ic->icsbrec_route_by_ts);
         icsbrec_route_index_set_transit_switch(isb_route_key,
                                                isb_pb->transit_switch);
 
         ICSBREC_ROUTE_FOR_EACH_EQUAL (isb_route, isb_route_key,
-                                      ctx->icsbrec_route_by_ts) {
+                                      ic->icsbrec_route_by_ts) {
             /* Filters ICSB routes, skipping those that either belong to
              * current logical router or are legacy routes from the current
              * availability zone (withoud lr-id).
@@ -2055,7 +2076,7 @@ sync_learned_routes(struct ic_context *ctx,
                     || uuid_equals(&ic_lr->lr->header_.uuid, &lr_uuid)) {
                     continue;
                 }
-            } else if (isb_route->availability_zone == ctx->runned_az) {
+            } else if (isb_route->availability_zone == ic->runned_az) {
                 continue;
             }
 
@@ -2117,7 +2138,8 @@ sync_learned_routes(struct ic_context *ctx,
             } else {
                 /* Create the missing route in NB. */
                 const struct nbrec_logical_router_static_route *nb_route =
-                    nbrec_logical_router_static_route_insert(ctx->ovnnb_txn);
+                    nbrec_logical_router_static_route_insert(
+                        ctx->ovnnb_idl_txn);
                 nbrec_logical_router_static_route_set_ip_prefix(nb_route,
                     isb_route->ip_prefix);
                 nbrec_logical_router_static_route_set_nexthop(nb_route,
@@ -2190,20 +2212,21 @@ ad_route_sync_external_ids(const struct ic_route_info 
*route_adv,
 
 /* Sync routes from routes_ad to IC-SB. */
 static void
-advertise_routes(struct ic_context *ctx,
+advertise_routes(struct engine_context *ctx,
+                 struct ic_input *ic,
                  const struct icsbrec_availability_zone *az,
                  const char *ts_name,
                  struct hmap *routes_ad)
 {
-    ovs_assert(ctx->ovnisb_txn);
+    ovs_assert(ctx->ovnisb_idl_txn);
     const struct icsbrec_route *isb_route;
     const struct icsbrec_route *isb_route_key =
-        icsbrec_route_index_init_row(ctx->icsbrec_route_by_ts_az);
+        icsbrec_route_index_init_row(ic->icsbrec_route_by_ts_az);
     icsbrec_route_index_set_transit_switch(isb_route_key, ts_name);
     icsbrec_route_index_set_availability_zone(isb_route_key, az);
 
     ICSBREC_ROUTE_FOR_EACH_EQUAL (isb_route, isb_route_key,
-                                  ctx->icsbrec_route_by_ts_az) {
+                                  ic->icsbrec_route_by_ts_az) {
         struct in6_addr prefix, nexthop;
         unsigned int plen;
 
@@ -2237,7 +2260,7 @@ advertise_routes(struct ic_context *ctx,
     /* Create the missing routes in IC-SB */
     struct ic_route_info *route_adv;
     HMAP_FOR_EACH_SAFE (route_adv, node, routes_ad) {
-        isb_route = icsbrec_route_insert(ctx->ovnisb_txn);
+        isb_route = icsbrec_route_insert(ctx->ovnisb_idl_txn);
         icsbrec_route_set_transit_switch(isb_route, ts_name);
         icsbrec_route_set_availability_zone(isb_route, az);
 
@@ -2273,7 +2296,7 @@ advertise_routes(struct ic_context *ctx,
 }
 
 static void
-build_ts_routes_to_adv(struct ic_context *ctx,
+build_ts_routes_to_adv(struct ic_input *ic,
                        struct ic_router_info *ic_lr,
                        struct hmap *routes_ad,
                        struct lport_addresses *ts_port_addrs,
@@ -2310,7 +2333,7 @@ build_ts_routes_to_adv(struct ic_context *ctx,
     /* Check directly-connected subnets of the LR */
     for (int i = 0; i < lr->n_ports; i++) {
         const struct nbrec_logical_router_port *lrp = lr->ports[i];
-        if (!lrp_is_ts_port(ctx, ic_lr, lrp->name)) {
+        if (!lrp_is_ts_port(ic, ic_lr, lrp->name)) {
             for (int j = 0; j < lrp->n_networks; j++) {
                 add_network_to_routes_ad(routes_ad, lrp->networks[j], lrp,
                                          ts_port_addrs,
@@ -2356,12 +2379,13 @@ build_ts_routes_to_adv(struct ic_context *ctx,
 }
 
 static void
-collect_lr_routes(struct ic_context *ctx,
+collect_lr_routes(struct ic_input *ic,
                   struct ic_router_info *ic_lr,
                   struct shash *routes_ad_by_ts)
 {
     const struct nbrec_nb_global *nb_global =
-        nbrec_nb_global_first(ctx->ovnnb_idl);
+        nbrec_nb_global_table_first(ic->nbrec_nb_global_table);
+
     ovs_assert(nb_global);
 
     const struct icsbrec_port_binding *isb_pb;
@@ -2374,10 +2398,10 @@ collect_lr_routes(struct ic_context *ctx,
     const struct icnbrec_transit_switch *t_sw;
     VECTOR_FOR_EACH (&ic_lr->isb_pbs, isb_pb) {
         key = icnbrec_transit_switch_index_init_row(
-            ctx->icnbrec_transit_switch_by_name);
+            ic->icnbrec_transit_switch_by_name);
         icnbrec_transit_switch_index_set_name(key, isb_pb->transit_switch);
         t_sw = icnbrec_transit_switch_index_find(
-             ctx->icnbrec_transit_switch_by_name, key);
+             ic->icnbrec_transit_switch_by_name, key);
         icnbrec_transit_switch_index_destroy_row(key);
         if (!t_sw) {
             continue;
@@ -2398,8 +2422,8 @@ collect_lr_routes(struct ic_context *ctx,
                          ic_lr->lr->name);
             continue;
         }
-        lrp_name = get_lrp_name_by_ts_port_name(ctx, isb_pb->logical_port);
-        lrp = get_lrp_by_lrp_name(ctx, lrp_name);
+        lrp_name = get_lrp_name_by_ts_port_name(ic, isb_pb->logical_port);
+        lrp = get_lrp_by_lrp_name(ic, lrp_name);
         if (lrp) {
             route_table = smap_get_def(&lrp->options, "route_table", "");
             route_tag = smap_get_def(&lrp->options, "ic-route-tag", "");
@@ -2407,34 +2431,34 @@ collect_lr_routes(struct ic_context *ctx,
             route_table = "";
             route_tag = "";
         }
-        build_ts_routes_to_adv(ctx, ic_lr, routes_ad, &ts_port_addrs,
+        build_ts_routes_to_adv(ic, ic_lr, routes_ad, &ts_port_addrs,
                                nb_global, route_table, route_tag, lrp);
         destroy_lport_addresses(&ts_port_addrs);
     }
 }
 
 static void
-delete_orphan_ic_routes(struct ic_context *ctx,
-                         const struct icsbrec_availability_zone *az)
+delete_orphan_ic_routes(struct ic_input *ic,
+                        const struct icsbrec_availability_zone *az)
 {
     const struct icsbrec_route *isb_route, *isb_route_key =
-        icsbrec_route_index_init_row(ctx->icsbrec_route_by_az);
+        icsbrec_route_index_init_row(ic->icsbrec_route_by_az);
     icsbrec_route_index_set_availability_zone(isb_route_key, az);
 
     const struct icnbrec_transit_switch *t_sw, *t_sw_key;
 
     ICSBREC_ROUTE_FOR_EACH_EQUAL (isb_route, isb_route_key,
-                                  ctx->icsbrec_route_by_az)
+                                  ic->icsbrec_route_by_az)
     {
         t_sw_key = icnbrec_transit_switch_index_init_row(
-            ctx->icnbrec_transit_switch_by_name);
+            ic->icnbrec_transit_switch_by_name);
         icnbrec_transit_switch_index_set_name(t_sw_key,
             isb_route->transit_switch);
         t_sw = icnbrec_transit_switch_index_find(
-            ctx->icnbrec_transit_switch_by_name, t_sw_key);
+            ic->icnbrec_transit_switch_by_name, t_sw_key);
         icnbrec_transit_switch_index_destroy_row(t_sw_key);
 
-        if (!t_sw || !find_lrp_of_nexthop(ctx, isb_route)) {
+        if (!t_sw || !find_lrp_of_nexthop(ic, isb_route)) {
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
             VLOG_INFO_RL(&rl, "Deleting orphan ICDB:Route: %s->%s (%s, rtb:%s,"
                          " transit switch: %s)", isb_route->ip_prefix,
@@ -2447,34 +2471,35 @@ delete_orphan_ic_routes(struct ic_context *ctx,
 }
 
 static void
-route_run(struct ic_context *ctx)
+route_run(struct engine_context *ctx,
+          struct ic_input *ic)
 {
-    if (!ctx->ovnisb_txn || !ctx->ovnnb_txn) {
+    if (!ctx->ovnisb_idl_txn || !ctx->ovnnb_idl_txn) {
         return;
     }
 
-    delete_orphan_ic_routes(ctx, ctx->runned_az);
+    delete_orphan_ic_routes(ic, ic->runned_az);
 
     struct hmap ic_lrs = HMAP_INITIALIZER(&ic_lrs);
     const struct icsbrec_port_binding *isb_pb;
     const struct icsbrec_port_binding *isb_pb_key =
-        icsbrec_port_binding_index_init_row(ctx->icsbrec_port_binding_by_az);
+        icsbrec_port_binding_index_init_row(ic->icsbrec_port_binding_by_az);
     icsbrec_port_binding_index_set_availability_zone(isb_pb_key,
-        ctx->runned_az);
+        ic->runned_az);
 
     /* Each port on TS maps to a logical router, which is stored in the
      * external_ids:router-id of the IC SB port_binding record.
      * Here we build info for interconnected Logical Router:
      * collect IC Port Binding to process routes sync later on. */
     ICSBREC_PORT_BINDING_FOR_EACH_EQUAL (isb_pb, isb_pb_key,
-                                         ctx->icsbrec_port_binding_by_az)
+                                         ic->icsbrec_port_binding_by_az)
     {
         if (ic_pb_get_type(isb_pb) == IC_ROUTER_PORT) {
             continue;
         }
         const struct nbrec_logical_switch_port *nb_lsp;
 
-        nb_lsp = get_lsp_by_ts_port_name(ctx, isb_pb->logical_port);
+        nb_lsp = get_lsp_by_ts_port_name(ic, isb_pb->logical_port);
         if (!strcmp(nb_lsp->type, "switch")) {
             VLOG_DBG("IC-SB Port_Binding '%s' on ts '%s' corresponds to a "
                      "switch port, not considering for route collection.",
@@ -2483,7 +2508,7 @@ route_run(struct ic_context *ctx)
         }
 
         const char *ts_lrp_name =
-            get_lrp_name_by_ts_port_name(ctx, isb_pb->logical_port);
+            get_lrp_name_by_ts_port_name(ic, isb_pb->logical_port);
         if (!ts_lrp_name) {
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
             VLOG_WARN_RL(&rl, "Route sync ignores port %s on ts %s because "
@@ -2501,7 +2526,8 @@ route_run(struct ic_context *ctx)
         }
 
         const struct nbrec_logical_router *lr
-            = nbrec_logical_router_get_for_uuid(ctx->ovnnb_idl, &lr_uuid);
+            = nbrec_logical_router_table_get_for_uuid(
+                ic->nbrec_logical_router_table, &lr_uuid);
         if (!lr) {
             continue;
         }
@@ -2522,8 +2548,8 @@ route_run(struct ic_context *ctx)
     struct ic_router_info *ic_lr;
     struct shash routes_ad_by_ts = SHASH_INITIALIZER(&routes_ad_by_ts);
     HMAP_FOR_EACH_SAFE (ic_lr, node, &ic_lrs) {
-        collect_lr_routes(ctx, ic_lr, &routes_ad_by_ts);
-        sync_learned_routes(ctx, ic_lr);
+        collect_lr_routes(ic, ic_lr, &routes_ad_by_ts);
+        sync_learned_routes(ctx, ic, ic_lr);
         vector_destroy(&ic_lr->isb_pbs);
         hmap_destroy(&ic_lr->routes_learned);
         hmap_remove(&ic_lrs, &ic_lr->node);
@@ -2531,7 +2557,7 @@ route_run(struct ic_context *ctx)
     }
     struct shash_node *node;
     SHASH_FOR_EACH (node, &routes_ad_by_ts) {
-        advertise_routes(ctx, ctx->runned_az, node->name, node->data);
+        advertise_routes(ctx, ic, ic->runned_az, node->name, node->data);
         hmap_destroy(node->data);
     }
     shash_destroy_free_data(&routes_ad_by_ts);
@@ -2665,18 +2691,18 @@ remove_unused_sb_records(struct hmap *local_sb_svcs_map)
 }
 
 static void
-create_pushed_svcs_mon(struct ic_context *ctx,
+create_pushed_svcs_mon(struct ic_input *ic,
                        struct hmap *pushed_svcs_map)
 {
     struct sbrec_service_monitor *key =
         sbrec_service_monitor_index_init_row(
-            ctx->sbrec_service_monitor_by_remote_type);
+            ic->sbrec_service_monitor_by_remote_type);
 
     sbrec_service_monitor_index_set_remote(key, true);
 
     const struct sbrec_service_monitor *sb_rec;
     SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,
-        ctx->sbrec_service_monitor_by_remote_type) {
+        ic->sbrec_service_monitor_by_remote_type) {
         const char *target_az_name = smap_get(&sb_rec->options,
                                               "az-name");
         if (!target_az_name) {
@@ -2684,7 +2710,7 @@ create_pushed_svcs_mon(struct ic_context *ctx,
         }
         create_service_monitor_info(pushed_svcs_map, sb_rec,
                                     &sb_rec->header_.uuid,
-                                    ctx->runned_az->name, target_az_name,
+                                    ic->runned_az->name, target_az_name,
                                     NULL, false);
     }
 
@@ -2692,22 +2718,22 @@ create_pushed_svcs_mon(struct ic_context *ctx,
 }
 
 static void
-create_synced_svcs_mon(struct ic_context *ctx,
+create_synced_svcs_mon(struct ic_input *ic,
                        struct hmap *synced_svcs_map)
 {
     struct icsbrec_service_monitor *key =
         icsbrec_service_monitor_index_init_row(
-          ctx->icsbrec_service_monitor_by_target_az);
+          ic->icsbrec_service_monitor_by_target_az);
 
     icsbrec_service_monitor_index_set_target_availability_zone(
-        key, ctx->runned_az->name);
+        key, ic->runned_az->name);
 
     const struct icsbrec_service_monitor *ic_rec;
     ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,
-        ctx->icsbrec_service_monitor_by_target_az) {
+        ic->icsbrec_service_monitor_by_target_az) {
 
         const struct sbrec_port_binding *pb =
-            find_sb_pb_by_name(ctx->sbrec_port_binding_by_name,
+            find_sb_pb_by_name(ic->sbrec_port_binding_by_name,
                                ic_rec->logical_port);
 
         if (!pb || !pb->up) {
@@ -2717,7 +2743,7 @@ create_synced_svcs_mon(struct ic_context *ctx,
         const char *chassis_name = pb->chassis ? pb->chassis->name : NULL;
         create_service_monitor_info(synced_svcs_map, ic_rec,
                                     &ic_rec->header_.uuid,
-                                    ctx->runned_az->name,
+                                    ic->runned_az->name,
                                     NULL, chassis_name, true);
     }
 
@@ -2725,22 +2751,22 @@ create_synced_svcs_mon(struct ic_context *ctx,
 }
 
 static void
-create_local_ic_svcs_map(struct ic_context *ctx,
+create_local_ic_svcs_map(struct ic_input *ic,
                          struct hmap *owned_svc_map)
 {
     struct icsbrec_service_monitor *key =
         icsbrec_service_monitor_index_init_row(
-          ctx->icsbrec_service_monitor_by_source_az);
+          ic->icsbrec_service_monitor_by_source_az);
 
     icsbrec_service_monitor_index_set_source_availability_zone(
-        key, ctx->runned_az->name);
+        key, ic->runned_az->name);
 
     const struct icsbrec_service_monitor *ic_rec;
     ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,
-        ctx->icsbrec_service_monitor_by_source_az) {
+        ic->icsbrec_service_monitor_by_source_az) {
         create_service_monitor_info(owned_svc_map, ic_rec,
                                     &ic_rec->header_.uuid,
-                                    ctx->runned_az->name, NULL,
+                                    ic->runned_az->name, NULL,
                                     NULL, true);
     }
 
@@ -2748,22 +2774,22 @@ create_local_ic_svcs_map(struct ic_context *ctx,
 }
 
 static void
-create_local_sb_svcs_map(struct ic_context *ctx,
+create_local_sb_svcs_map(struct ic_input *ic,
                          struct hmap *owned_svc_map)
 {
     struct sbrec_service_monitor *key =
         sbrec_service_monitor_index_init_row(
-          ctx->sbrec_service_monitor_by_ic_learned);
+          ic->sbrec_service_monitor_by_ic_learned);
 
     sbrec_service_monitor_index_set_ic_learned(
         key, true);
 
     const struct sbrec_service_monitor *sb_rec;
     SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,
-        ctx->sbrec_service_monitor_by_ic_learned) {
+        ic->sbrec_service_monitor_by_ic_learned) {
         create_service_monitor_info(owned_svc_map, sb_rec,
                                     &sb_rec->header_.uuid,
-                                    ctx->runned_az->name, NULL,
+                                    ic->runned_az->name, NULL,
                                     NULL, false);
     }
 
@@ -2771,21 +2797,21 @@ create_local_sb_svcs_map(struct ic_context *ctx,
 }
 
 static const struct sbrec_service_monitor *
-lookup_sb_svc_rec(struct ic_context *ctx,
+lookup_sb_svc_rec(struct ic_input *ic,
                   const struct service_monitor_info *svc_mon)
 {
     const struct icsbrec_service_monitor *db_rec =
         svc_mon->db_rec.ic_rec;
     struct sbrec_service_monitor *key =
         sbrec_service_monitor_index_init_row(
-            ctx->sbrec_service_monitor_by_remote_type_logical_port);
+            ic->sbrec_service_monitor_by_remote_type_logical_port);
 
     sbrec_service_monitor_index_set_remote(key, false);
     sbrec_service_monitor_index_set_logical_port(key, db_rec->logical_port);
 
     const struct sbrec_service_monitor *sb_rec;
     SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,
-        ctx->sbrec_service_monitor_by_remote_type_logical_port) {
+        ic->sbrec_service_monitor_by_remote_type_logical_port) {
         if (db_rec->port == sb_rec->port &&
             ((db_rec->type && sb_rec->type &&
               !strcmp(db_rec->type, sb_rec->type)) ||
@@ -2804,14 +2830,14 @@ lookup_sb_svc_rec(struct ic_context *ctx,
 }
 
 static const struct icsbrec_service_monitor *
-lookup_icsb_svc_rec(struct ic_context *ctx,
+lookup_icsb_svc_rec(struct ic_input *ic,
                     const struct service_monitor_info *svc_mon)
 {
     const struct sbrec_service_monitor *db_rec =
        svc_mon->db_rec.sb_rec;
     struct icsbrec_service_monitor *key =
         icsbrec_service_monitor_index_init_row(
-        ctx->icsbrec_service_monitor_by_target_az_logical_port);
+        ic->icsbrec_service_monitor_by_target_az_logical_port);
 
     ovs_assert(svc_mon->dst_az_name);
     icsbrec_service_monitor_index_set_target_availability_zone(
@@ -2822,7 +2848,7 @@ lookup_icsb_svc_rec(struct ic_context *ctx,
 
     const struct icsbrec_service_monitor *ic_rec;
     ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,
-        ctx->icsbrec_service_monitor_by_target_az_logical_port) {
+        ic->icsbrec_service_monitor_by_target_az_logical_port) {
         if (db_rec->port == ic_rec->port &&
             ((db_rec->type && ic_rec->type &&
               !strcmp(db_rec->type, ic_rec->type)) ||
@@ -2842,11 +2868,11 @@ lookup_icsb_svc_rec(struct ic_context *ctx,
 }
 
 static void
-create_service_monitor_data(struct ic_context *ctx,
+create_service_monitor_data(struct ic_input *ic,
                             struct sync_service_monitor_data *sync_data)
 {
-    const struct sbrec_sb_global *ic_sb = sbrec_sb_global_first(
-                                                ctx->ovnsb_idl);
+    const struct sbrec_sb_global *ic_sb =
+        sbrec_sb_global_table_first(ic->sbrec_sb_global_table);
     const char *svc_monitor_mac = smap_get(&ic_sb->options,
                                            "svc_monitor_mac");
 
@@ -2855,10 +2881,10 @@ create_service_monitor_data(struct ic_context *ctx,
     }
 
     sync_data->prpg_svc_monitor_mac = xstrdup(svc_monitor_mac);
-    create_pushed_svcs_mon(ctx, &sync_data->pushed_svcs_map);
-    create_synced_svcs_mon(ctx, &sync_data->synced_svcs_map);
-    create_local_ic_svcs_map(ctx, &sync_data->local_ic_svcs_map);
-    create_local_sb_svcs_map(ctx, &sync_data->local_sb_svcs_map);
+    create_pushed_svcs_mon(ic, &sync_data->pushed_svcs_map);
+    create_synced_svcs_mon(ic, &sync_data->synced_svcs_map);
+    create_local_ic_svcs_map(ic, &sync_data->local_ic_svcs_map);
+    create_local_sb_svcs_map(ic, &sync_data->local_sb_svcs_map);
 }
 
 static void
@@ -2879,9 +2905,10 @@ destroy_service_monitor_data(struct 
sync_service_monitor_data *sync_data)
 }
 
 static void
-sync_service_monitor(struct ic_context *ctx)
+sync_service_monitor(struct engine_context *ctx,
+                     struct ic_input *ic)
 {
-    if (!ctx->ovnisb_txn || !ctx->ovnsb_txn) {
+    if (!ctx->ovnisb_idl_txn || !ctx->ovnsb_idl_txn) {
         return;
     }
 
@@ -2892,18 +2919,18 @@ sync_service_monitor(struct ic_context *ctx)
     hmap_init(&sync_data.local_ic_svcs_map);
     hmap_init(&sync_data.local_sb_svcs_map);
 
-    create_service_monitor_data(ctx, &sync_data);
+    create_service_monitor_data(ic, &sync_data);
 
     struct service_monitor_info *svc_mon;
     HMAP_FOR_EACH_SAFE (svc_mon, hmap_node, &sync_data.pushed_svcs_map) {
         const struct sbrec_service_monitor *db_rec = svc_mon->db_rec.sb_rec;
         const struct icsbrec_service_monitor *ic_rec =
-            lookup_icsb_svc_rec(ctx, svc_mon);
+            lookup_icsb_svc_rec(ic, svc_mon);
 
         if (ic_rec) {
             sbrec_service_monitor_set_status(db_rec, ic_rec->status);
         } else {
-            ic_rec = icsbrec_service_monitor_insert(ctx->ovnisb_txn);
+            ic_rec = icsbrec_service_monitor_insert(ctx->ovnisb_idl_txn);
             icsbrec_service_monitor_set_type(ic_rec, db_rec->type);
             icsbrec_service_monitor_set_ip(ic_rec, db_rec->ip);
             icsbrec_service_monitor_set_port(ic_rec, db_rec->port);
@@ -2928,13 +2955,13 @@ sync_service_monitor(struct ic_context *ctx)
         const struct icsbrec_service_monitor *db_rec =
             svc_mon->db_rec.ic_rec;
         const struct sbrec_service_monitor *sb_rec =
-            lookup_sb_svc_rec(ctx, svc_mon);
+            lookup_sb_svc_rec(ic, svc_mon);
 
         if (sb_rec) {
             icsbrec_service_monitor_set_status(svc_mon->db_rec.ic_rec,
                                                sb_rec->status);
         } else {
-            sb_rec = sbrec_service_monitor_insert(ctx->ovnsb_txn);
+            sb_rec = sbrec_service_monitor_insert(ctx->ovnsb_idl_txn);
             sbrec_service_monitor_set_type(sb_rec, db_rec->type);
             sbrec_service_monitor_set_ip(sb_rec, db_rec->ip);
             sbrec_service_monitor_set_port(sb_rec, db_rec->port);
@@ -3002,32 +3029,36 @@ sync_service_monitor(struct ic_context *ctx)
  *    INB:nb_ic_cfg and INB:sb_ic_cfg to INB:nb_ic_cfg.
  */
 static void
-update_sequence_numbers(struct ic_context *ctx,
-                        struct ovsdb_idl_loop *ic_sb_loop)
-{
-    if (!ctx->ovnisb_txn || !ctx->ovninb_txn) {
+update_sequence_numbers(struct ovsdb_idl *ovninb_idl,
+                        struct ovsdb_idl *ovnisb_idl,
+                        struct ovsdb_idl_txn *ovninb_txn,
+                        struct ovsdb_idl_txn *ovnisb_txn,
+                        struct ovsdb_idl_loop *ic_sb_loop,
+                        const struct icsbrec_availability_zone *az)
+{
+    if (!ovnisb_txn || !ovninb_txn) {
         return;
     }
 
     const struct icnbrec_ic_nb_global *ic_nb = icnbrec_ic_nb_global_first(
-                                               ctx->ovninb_idl);
+                                               ovninb_idl);
     if (!ic_nb) {
-        ic_nb = icnbrec_ic_nb_global_insert(ctx->ovninb_txn);
+        ic_nb = icnbrec_ic_nb_global_insert(ovninb_txn);
     }
     const struct icsbrec_ic_sb_global *ic_sb = icsbrec_ic_sb_global_first(
-                                               ctx->ovnisb_idl);
+                                               ovnisb_idl);
     if (!ic_sb) {
-        ic_sb = icsbrec_ic_sb_global_insert(ctx->ovnisb_txn);
+        ic_sb = icsbrec_ic_sb_global_insert(ovnisb_txn);
     }
 
     if ((ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) &&
-                          (ic_nb->nb_ic_cfg != ctx->runned_az->nb_ic_cfg)) {
+                          (ic_nb->nb_ic_cfg != az->nb_ic_cfg)) {
         /* Deal with potential overflows. */
-        if (ctx->runned_az->nb_ic_cfg == INT64_MAX) {
-            icsbrec_availability_zone_set_nb_ic_cfg(ctx->runned_az, 0);
+        if (az->nb_ic_cfg == INT64_MAX) {
+            icsbrec_availability_zone_set_nb_ic_cfg(az, 0);
         }
         ic_sb_loop->next_cfg = ic_nb->nb_ic_cfg;
-        ovsdb_idl_txn_increment(ctx->ovnisb_txn, &ctx->runned_az->header_,
+        ovsdb_idl_txn_increment(ovnisb_txn, &az->header_,
             &icsbrec_availability_zone_col_nb_ic_cfg, true);
         return;
     }
@@ -3035,22 +3066,22 @@ update_sequence_numbers(struct ic_context *ctx,
     /* handle cases where accidentally AZ:ic_nb_cfg exceeds
      * the INB:ic_nb_cfg.
      */
-    if (ctx->runned_az->nb_ic_cfg != ic_sb_loop->cur_cfg) {
-        icsbrec_availability_zone_set_nb_ic_cfg(ctx->runned_az,
+    if (az->nb_ic_cfg != ic_sb_loop->cur_cfg) {
+        icsbrec_availability_zone_set_nb_ic_cfg(az,
                                                 ic_sb_loop->cur_cfg);
         return;
     }
 
     const struct icsbrec_availability_zone *other_az;
-    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ctx->ovnisb_idl) {
-        if (other_az->nb_ic_cfg != ctx->runned_az->nb_ic_cfg) {
+    ICSBREC_AVAILABILITY_ZONE_FOR_EACH (other_az, ovnisb_idl) {
+        if (other_az->nb_ic_cfg != az->nb_ic_cfg) {
             return;
         }
     }
     /* All the AZs are updated successfully, update SB/NB counter. */
     if (ic_nb->nb_ic_cfg != ic_sb->nb_ic_cfg) {
-        icsbrec_ic_sb_global_set_nb_ic_cfg(ic_sb, ctx->runned_az->nb_ic_cfg);
-        icnbrec_ic_nb_global_set_sb_ic_cfg(ic_nb, ctx->runned_az->nb_ic_cfg);
+        icsbrec_ic_sb_global_set_nb_ic_cfg(ic_sb, az->nb_ic_cfg);
+        icnbrec_ic_nb_global_set_sb_ic_cfg(ic_nb, az->nb_ic_cfg);
     }
 }
 
@@ -3077,23 +3108,18 @@ inc_proc_graph_dump(const char *end_node)
 }
 
 void
-ovn_db_run(struct ic_context *ctx)
-{
-    struct hmap dp_tnlids = HMAP_INITIALIZER(&dp_tnlids);
-    struct shash isb_ts_dps = SHASH_INITIALIZER(&isb_ts_dps);
-    struct shash isb_tr_dps = SHASH_INITIALIZER(&isb_tr_dps);
-
-    gateway_run(ctx);
-    enumerate_datapaths(ctx, &dp_tnlids, &isb_ts_dps, &isb_tr_dps);
-    ts_run(ctx, &dp_tnlids, &isb_ts_dps);
-    tr_run(ctx, &dp_tnlids, &isb_tr_dps);
-    port_binding_run(ctx);
-    route_run(ctx);
-    sync_service_monitor(ctx);
-
-    ovn_destroy_tnlids(&dp_tnlids);
-    shash_destroy(&isb_ts_dps);
-    shash_destroy(&isb_tr_dps);
+ovn_db_run(struct ic_input *input_data,
+           struct ic_data *ic_data,
+           struct engine_context *eng_ctx)
+{
+    gateway_run(eng_ctx, input_data);
+    enumerate_datapaths(input_data, &ic_data->dp_tnlids,
+                        &ic_data->isb_ts_dps, &ic_data->isb_tr_dps);
+    ts_run(eng_ctx, input_data, &ic_data->dp_tnlids, &ic_data->isb_ts_dps);
+    tr_run(eng_ctx, input_data, &ic_data->dp_tnlids, &ic_data->isb_tr_dps);
+    port_binding_run(eng_ctx, input_data);
+    route_run(eng_ctx, input_data);
+    sync_service_monitor(eng_ctx, input_data);
 }
 
 static void
@@ -3485,81 +3511,6 @@ main(int argc, char *argv[])
     ovsdb_idl_track_add_column(ovnsb_idl_loop.idl,
                                &sbrec_service_monitor_col_options);
 
-    /* Create IDL indexes */
-    struct ovsdb_idl_index *nbrec_ls_by_name
-        = ovsdb_idl_index_create1(ovnnb_idl_loop.idl,
-                                  &nbrec_logical_switch_col_name);
-    struct ovsdb_idl_index *nbrec_lr_by_name = ovsdb_idl_index_create1(
-        ovnnb_idl_loop.idl, &nbrec_logical_router_col_name);
-    struct ovsdb_idl_index *nbrec_port_by_name
-        = ovsdb_idl_index_create1(ovnnb_idl_loop.idl,
-                                  &nbrec_logical_switch_port_col_name);
-    struct ovsdb_idl_index *nbrec_lrp_by_name
-        = ovsdb_idl_index_create1(ovnnb_idl_loop.idl,
-                                  &nbrec_logical_router_port_col_name);
-    struct ovsdb_idl_index *sbrec_port_binding_by_name
-        = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
-                                  &sbrec_port_binding_col_logical_port);
-    struct ovsdb_idl_index *sbrec_chassis_by_name
-        = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
-                                  &sbrec_chassis_col_name);
-
-    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type
-        = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
-                                  &sbrec_service_monitor_col_remote);
-
-    struct ovsdb_idl_index *sbrec_service_monitor_by_ic_learned
-        = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
-                                  &sbrec_service_monitor_col_ic_learned);
-
-    struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type_logical_port
-        = ovsdb_idl_index_create2(ovnsb_idl_loop.idl,
-                                  &sbrec_service_monitor_col_remote,
-                                  &sbrec_service_monitor_col_logical_port);
-
-    struct ovsdb_idl_index *icnbrec_transit_switch_by_name
-        = ovsdb_idl_index_create1(ovninb_idl_loop.idl,
-                                  &icnbrec_transit_switch_col_name);
-
-    struct ovsdb_idl_index *icsbrec_port_binding_by_az
-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,
-                                  &icsbrec_port_binding_col_availability_zone);
-
-    struct ovsdb_idl_index *icsbrec_port_binding_by_ts
-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,
-                                  &icsbrec_port_binding_col_transit_switch);
-
-    struct ovsdb_idl_index *icsbrec_port_binding_by_ts_az
-        = ovsdb_idl_index_create2(ovnisb_idl_loop.idl,
-                                  &icsbrec_port_binding_col_transit_switch,
-                                  &icsbrec_port_binding_col_availability_zone);
-
-    struct ovsdb_idl_index *icsbrec_route_by_az
-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,
-                                  &icsbrec_route_col_availability_zone);
-
-    struct ovsdb_idl_index *icsbrec_route_by_ts
-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,
-                                  &icsbrec_route_col_transit_switch);
-
-    struct ovsdb_idl_index *icsbrec_route_by_ts_az
-        = ovsdb_idl_index_create2(ovnisb_idl_loop.idl,
-                                  &icsbrec_route_col_transit_switch,
-                                  &icsbrec_route_col_availability_zone);
-
-    struct ovsdb_idl_index *icsbrec_service_monitor_by_source_az
-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,
-            &icsbrec_service_monitor_col_source_availability_zone);
-
-    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az
-        = ovsdb_idl_index_create1(ovnisb_idl_loop.idl,
-            &icsbrec_service_monitor_col_target_availability_zone);
-
-    struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az_logical_port
-        = ovsdb_idl_index_create2(ovnisb_idl_loop.idl,
-            &icsbrec_service_monitor_col_target_availability_zone,
-            &icsbrec_service_monitor_col_logical_port);
-
     unixctl_command_register("nb-connection-status", "", 0, 0,
                              ovn_conn_show, ovnnb_idl_loop.idl);
     unixctl_command_register("sb-connection-status", "", 0, 0,
@@ -3569,6 +3520,9 @@ main(int argc, char *argv[])
     unixctl_command_register("ic-sb-connection-status", "", 0, 0,
                              ovn_conn_show, ovnisb_idl_loop.idl);
 
+    stopwatch_create(OVN_IC_LOOP_STOPWATCH_NAME, SW_MS);
+    stopwatch_create(IC_OVN_DB_RUN_STOPWATCH_NAME, SW_MS);
+
     /* Initialize incremental processing engine for ovn-northd */
     inc_proc_ic_init(&ovnnb_idl_loop, &ovnsb_idl_loop,
                      &ovninb_idl_loop, &ovnisb_idl_loop);
@@ -3662,67 +3616,43 @@ main(int argc, char *argv[])
                 ovnisb_cond_seqno = new_ovnisb_cond_seqno;
             }
 
-            struct ic_context ctx = {
-                .ovnnb_idl = ovnnb_idl_loop.idl,
-                .ovnnb_txn = ovnnb_txn,
-                .ovnsb_idl = ovnsb_idl_loop.idl,
-                .ovnsb_txn = ovnsb_txn,
-                .ovninb_idl = ovninb_idl_loop.idl,
-                .ovninb_txn = ovninb_txn,
-                .ovnisb_idl = ovnisb_idl_loop.idl,
-                .ovnisb_txn = ovnisb_txn,
-                .nbrec_ls_by_name = nbrec_ls_by_name,
-                .nbrec_lr_by_name = nbrec_lr_by_name,
-                .nbrec_lrp_by_name = nbrec_lrp_by_name,
-                .nbrec_port_by_name = nbrec_port_by_name,
-                .sbrec_port_binding_by_name = sbrec_port_binding_by_name,
-                .sbrec_chassis_by_name = sbrec_chassis_by_name,
-                .sbrec_service_monitor_by_remote_type =
-                    sbrec_service_monitor_by_remote_type,
-                .sbrec_service_monitor_by_ic_learned =
-                    sbrec_service_monitor_by_ic_learned,
-                .sbrec_service_monitor_by_remote_type_logical_port =
-                    sbrec_service_monitor_by_remote_type_logical_port,
-                .icnbrec_transit_switch_by_name =
-                    icnbrec_transit_switch_by_name,
-                .icsbrec_port_binding_by_az = icsbrec_port_binding_by_az,
-                .icsbrec_port_binding_by_ts = icsbrec_port_binding_by_ts,
-                .icsbrec_port_binding_by_ts_az = icsbrec_port_binding_by_ts_az,
-                .icsbrec_route_by_az = icsbrec_route_by_az,
-                .icsbrec_route_by_ts = icsbrec_route_by_ts,
-                .icsbrec_route_by_ts_az = icsbrec_route_by_ts_az,
-                .icsbrec_service_monitor_by_source_az =
-                    icsbrec_service_monitor_by_source_az,
-                .icsbrec_service_monitor_by_target_az =
-                    icsbrec_service_monitor_by_target_az,
-                .icsbrec_service_monitor_by_target_az_logical_port =
-                    icsbrec_service_monitor_by_target_az_logical_port,
-            };
-
-            if (!state.had_lock && ovsdb_idl_has_lock(ctx.ovnsb_idl)) {
+            if (!state.had_lock && ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) {
                 VLOG_INFO("ovn-ic lock acquired. "
                             "This ovn-ic instance is now active.");
                 state.had_lock = true;
             } else if (state.had_lock &&
-                       !ovsdb_idl_has_lock(ctx.ovnsb_idl)) {
+                       !ovsdb_idl_has_lock(ovnsb_idl_loop.idl)) {
                 VLOG_INFO("ovn-ic lock lost. "
                             "This ovn-ic instance is now on standby.");
                 state.had_lock = false;
             }
 
-            if (ovsdb_idl_has_lock(ctx.ovnsb_idl) &&
-                ovsdb_idl_has_ever_connected(ctx.ovnnb_idl) &&
-                ovsdb_idl_has_ever_connected(ctx.ovnsb_idl) &&
-                ovsdb_idl_has_ever_connected(ctx.ovninb_idl) &&
-                ovsdb_idl_has_ever_connected(ctx.ovnisb_idl)) {
-                if (ctx.ovnnb_txn && ctx.ovnsb_txn && ctx.ovninb_txn &&
-                    ctx.ovnisb_txn && inc_proc_ic_can_run(&eng_ctx)) {
-                    ctx.runned_az = az_run(&ctx);
-                    VLOG_DBG("Availability zone: %s", ctx.runned_az ?
-                             ctx.runned_az->name : "not created yet.");
-                    if (ctx.runned_az) {
-                        (void) inc_proc_ic_run(&ctx, &eng_ctx);
-                        update_sequence_numbers(&ctx, &ovnisb_idl_loop);
+            if (ovsdb_idl_has_lock(ovnsb_idl_loop.idl) &&
+                ovsdb_idl_has_ever_connected(ovnnb_idl_loop.idl) &&
+                ovsdb_idl_has_ever_connected(ovnsb_idl_loop.idl) &&
+                ovsdb_idl_has_ever_connected(ovninb_idl_loop.idl) &&
+                ovsdb_idl_has_ever_connected(ovnisb_idl_loop.idl)) {
+                if (ovnnb_txn && ovnsb_txn && ovninb_txn &&
+                    ovnisb_txn && inc_proc_ic_can_run(&eng_ctx)) {
+                    const struct icsbrec_availability_zone *az =
+                        az_run(ovnnb_idl_loop.idl,
+                               ovnisb_idl_loop.idl,
+                               ovnisb_txn);
+                    VLOG_DBG("Availability zone: %s", az ?
+                             az->name : "not created yet.");
+                    if (az) {
+                        (void) inc_proc_ic_run(ovnnb_txn,
+                                               ovnsb_txn,
+                                               ovninb_txn,
+                                               ovnisb_txn,
+                                               &eng_ctx,
+                                               az);
+                        update_sequence_numbers(ovninb_idl_loop.idl,
+                                                ovnisb_idl_loop.idl,
+                                                ovninb_txn,
+                                                ovnisb_txn,
+                                                &ovnisb_idl_loop,
+                                                az);
                     }
                 } else if (!inc_proc_ic_get_force_recompute()) {
                     clear_idl_track = false;
@@ -3812,10 +3742,12 @@ main(int argc, char *argv[])
             poll_immediate_wake();
         }
 
+        stopwatch_stop(NORTHD_LOOP_STOPWATCH_NAME, time_msec());
         poll_block();
         if (should_service_stop()) {
             exiting = true;
         }
+        stopwatch_start(NORTHD_LOOP_STOPWATCH_NAME, time_msec());
     }
     inc_proc_ic_cleanup();
 
@@ -3885,8 +3817,8 @@ ovn_ic_status(struct unixctl_conn *conn, int argc 
OVS_UNUSED,
     }
 
     /*
-     * Use a labelled formatted output so we can add more to the status command
-     * later without breaking any consuming scripts
+     * Use a labelled formatted output so we can add more to the status
+     * command later without breaking any consuming scripts
      */
     struct ds s = DS_EMPTY_INITIALIZER;
     ds_put_format(&s, "Status: %s\n", status);
diff --git a/ic/ovn-ic.h b/ic/ovn-ic.h
index e8d7a970f..2c2efc046 100644
--- a/ic/ovn-ic.h
+++ b/ic/ovn-ic.h
@@ -16,16 +16,33 @@
 
 #include "ovsdb-idl.h"
 #include "unixctl.h"
+#include "lib/inc-proc-eng.h"
 
-struct ic_context {
-    struct ovsdb_idl *ovnnb_idl;
-    struct ovsdb_idl *ovnsb_idl;
-    struct ovsdb_idl *ovninb_idl;
-    struct ovsdb_idl *ovnisb_idl;
-    struct ovsdb_idl_txn *ovnnb_txn;
-    struct ovsdb_idl_txn *ovnsb_txn;
-    struct ovsdb_idl_txn *ovninb_txn;
-    struct ovsdb_idl_txn *ovnisb_txn;
+struct ic_input {
+    /* Northbound table references */
+    const struct nbrec_logical_switch_table *nbrec_logical_switch_table;
+    const struct nbrec_logical_router_table *nbrec_logical_router_table;
+    const struct nbrec_nb_global_table *nbrec_nb_global_table;
+
+    /* Southbound table references */
+    const struct sbrec_chassis_table *sbrec_chassis_table;
+    const struct sbrec_sb_global_table *sbrec_sb_global_table;
+
+    /* InterconnectNorthbound table references */
+    const struct icnbrec_transit_switch_table *icnbrec_transit_switch_table;
+    const struct icnbrec_ic_nb_global_table *icnbrec_ic_nb_global_table;
+    const struct icnbrec_transit_router_table *icnbrec_transit_router_table;
+
+    /* InterconnectSouthbound table references */
+    const struct icsbrec_encap_table *icsbrec_encap_table;
+    const struct icsbrec_gateway_table *icsbrec_gateway_table;
+    const struct icsbrec_ic_sb_global_table *icsbrec_ic_sb_global_table;
+    const struct icsbrec_datapath_binding_table
+        *icsbrec_datapath_binding_table;
+    const struct icsbrec_availability_zone_table
+        *icsbrec_availability_zone_table;
+
+    /* Indexes */
     const struct icsbrec_availability_zone *runned_az;
     struct ovsdb_idl_index *nbrec_ls_by_name;
     struct ovsdb_idl_index *nbrec_lr_by_name;
@@ -48,6 +65,12 @@ struct ic_context {
     struct ovsdb_idl_index *icsbrec_service_monitor_by_target_az_logical_port;
 };
 
+struct ic_data {
+    /* Global state for 'en-ic'. */
+    struct hmap dp_tnlids;
+    struct shash isb_ts_dps;
+    struct shash isb_tr_dps;
+};
 struct ic_state {
     bool had_lock;
     bool paused;
@@ -56,6 +79,13 @@ struct ic_state {
 enum ic_datapath_type { IC_SWITCH, IC_ROUTER, IC_DATAPATH_MAX };
 enum ic_port_binding_type { IC_SWITCH_PORT, IC_ROUTER_PORT, IC_PORT_MAX };
 
-void ovn_db_run(struct ic_context *ctx);
+const struct icsbrec_availability_zone *
+    az_run(struct ovsdb_idl *ovnnb_idl,
+           struct ovsdb_idl *ovnisb_idl,
+           struct ovsdb_idl_txn *ovnisb_idl_txn);
+
+void ovn_db_run(struct ic_input *input_data,
+                struct ic_data *ic_data,
+                struct engine_context *eng_ctx);
 
 #endif /* OVN_IC_H */
diff --git a/lib/stopwatch-names.h b/lib/stopwatch-names.h
index b912e813c..5f1091155 100644
--- a/lib/stopwatch-names.h
+++ b/lib/stopwatch-names.h
@@ -40,4 +40,7 @@
 #define DYNAMIC_ROUTES_RUN_STOPWATCH_NAME "dynamic_routes"
 #define GROUP_ECMP_ROUTE_RUN_STOPWATCH_NAME "group_ecmp_route"
 
+#define OVN_IC_LOOP_STOPWATCH_NAME "ovn-ic-loop"
+#define IC_OVN_DB_RUN_STOPWATCH_NAME "ovn_db_run"
+
 #endif
-- 
2.34.1


-- 




_'Esta mensagem é direcionada apenas para os endereços constantes no 
cabeçalho inicial. Se você não está listado nos endereços constantes no 
cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa 
mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão 
imediatamente anuladas e proibidas'._


* **'Apesar do Magazine Luiza tomar 
todas as precauções razoáveis para assegurar que nenhum vírus esteja 
presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por 
quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.*



_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to