This patch handles the logical switch creation incrementally
in the northd engine node.  The dependent engine nodes - ls_stateful,
lflow and few others still fall back to full recompute, which
will be handled in separate patches.

Reported-at: https://issues.redhat.com/browse/FDP-754
Co-authored-by: Numan Siddique <num...@ovn.org>
Signed-off-by: Numan Siddique <num...@ovn.org>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com>
---
 northd/en-datapath-logical-switch.c |  16 +++
 northd/en-datapath-logical-switch.h |   4 +
 northd/en-lflow.c                   |   4 +
 northd/en-ls-stateful.c             |   4 +
 northd/en-northd.c                  |  16 +++
 northd/en-northd.h                  |   2 +
 northd/inc-proc-northd.c            |   8 +-
 northd/northd.c                     | 174 +++++++++++++++++++++++++++-
 northd/northd.h                     |  19 +++
 tests/ovn-northd.at                 |  70 ++++++++++-
 10 files changed, 308 insertions(+), 9 deletions(-)

diff --git a/northd/en-datapath-logical-switch.c 
b/northd/en-datapath-logical-switch.c
index 2ef2f7d9a..34b29ab92 100644
--- a/northd/en-datapath-logical-switch.c
+++ b/northd/en-datapath-logical-switch.c
@@ -139,6 +139,22 @@ en_datapath_synced_logical_switch_init(struct engine_node 
*node OVS_UNUSED,
     return switch_map;
 }
 
+struct ovn_synced_logical_switch *
+datapath_synced_logical_switch_find(
+        const struct ovn_synced_logical_switch_map *switch_map,
+        const struct nbrec_logical_switch *nb_ls)
+{
+    struct ovn_synced_logical_switch *lsw;
+    HMAP_FOR_EACH_WITH_HASH (lsw, hmap_node, uuid_hash(&nb_ls->header_.uuid),
+                             &switch_map->synced_switches) {
+        if (!strcmp(lsw->nb->name, nb_ls->name)) {
+            return lsw;
+        }
+    }
+    return NULL;
+}
+
+
 enum engine_node_state
 en_datapath_synced_logical_switch_run(struct engine_node *node , void *data)
 {
diff --git a/northd/en-datapath-logical-switch.h 
b/northd/en-datapath-logical-switch.h
index 1190b7be8..8e2f497c0 100644
--- a/northd/en-datapath-logical-switch.h
+++ b/northd/en-datapath-logical-switch.h
@@ -41,6 +41,10 @@ struct ovn_synced_logical_switch_map {
 void *en_datapath_synced_logical_switch_init(struct engine_node *,
                                              struct engine_arg *);
 
+struct ovn_synced_logical_switch *
+datapath_synced_logical_switch_find(
+        const struct ovn_synced_logical_switch_map *switch_map,
+        const struct nbrec_logical_switch *nb_ls);
 enum engine_node_state en_datapath_synced_logical_switch_run(
     struct engine_node *, void *data);
 void en_datapath_synced_logical_switch_cleanup(void *data);
diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index 63565ef80..539113556 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -135,6 +135,10 @@ lflow_northd_handler(struct engine_node *node,
         return EN_UNHANDLED;
     }
 
+    if (northd_has_lswitchs_in_tracked_data(&northd_data->trk_data)) {
+        return EN_UNHANDLED;
+    }
+
     const struct engine_context *eng_ctx = engine_get_context();
     struct lflow_data *lflow_data = data;
 
diff --git a/northd/en-ls-stateful.c b/northd/en-ls-stateful.c
index 7f07a6506..448ccc3c4 100644
--- a/northd/en-ls-stateful.c
+++ b/northd/en-ls-stateful.c
@@ -131,6 +131,10 @@ ls_stateful_northd_handler(struct engine_node *node, void 
*data_)
         return EN_UNHANDLED;
     }
 
+    if (northd_has_lswitchs_in_tracked_data(&northd_data->trk_data)) {
+        return EN_UNHANDLED;
+    }
+
     if (!northd_has_ls_lbs_in_tracked_data(&northd_data->trk_data) &&
         !northd_has_ls_acls_in_tracked_data(&northd_data->trk_data)) {
         return EN_HANDLED_UNCHANGED;
diff --git a/northd/en-northd.c b/northd/en-northd.c
index 02be1968e..f2bc80c57 100644
--- a/northd/en-northd.c
+++ b/northd/en-northd.c
@@ -182,6 +182,22 @@ northd_nb_logical_switch_handler(struct engine_node *node,
     return EN_HANDLED_UNCHANGED;
 }
 
+enum engine_input_handler_result
+northd_sb_datapath_binding_handler(struct engine_node *node, void *data)
+{
+    struct northd_input input_data;
+    struct northd_data *nd = data;
+
+    northd_get_input_data(node, &input_data);
+    if (!northd_handle_sb_datapath_binding_changes(
+            input_data.sbrec_datapath_binding_table, &nd->ls_datapaths,
+            &nd->lr_datapaths)) {
+        return EN_UNHANDLED;
+    }
+
+    return EN_HANDLED_UPDATED;
+}
+
 enum engine_input_handler_result
 northd_sb_port_binding_handler(struct engine_node *node,
                                void *data)
diff --git a/northd/en-northd.h b/northd/en-northd.h
index 4f744a6c5..740e2d30b 100644
--- a/northd/en-northd.h
+++ b/northd/en-northd.h
@@ -23,6 +23,8 @@ enum engine_input_handler_result
 northd_nb_logical_router_handler(struct engine_node *, void *data);
 enum engine_input_handler_result
 northd_sb_port_binding_handler(struct engine_node *, void *data);
+enum engine_input_handler_result
+northd_sb_datapath_binding_handler(struct engine_node *, void *data);
 enum engine_input_handler_result northd_lb_data_handler(struct engine_node *,
                                                         void *data);
 enum engine_input_handler_result
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index 7aa4bdf3f..08483dfd0 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -284,10 +284,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_northd, &en_sb_chassis, NULL);
     engine_add_input(&en_northd, &en_sb_mirror, NULL);
     engine_add_input(&en_northd, &en_sb_meter, NULL);
-    engine_add_input(&en_northd, &en_sb_datapath_binding, NULL);
     engine_add_input(&en_northd, &en_sb_dns, NULL);
     engine_add_input(&en_northd, &en_sb_ha_chassis_group, NULL);
-    engine_add_input(&en_northd, &en_sb_ip_multicast, NULL);
     engine_add_input(&en_northd, &en_sb_service_monitor, NULL);
     engine_add_input(&en_northd, &en_sb_static_mac_binding, NULL);
     engine_add_input(&en_northd, &en_sb_chassis_template_var, NULL);
@@ -306,6 +304,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_northd, &en_sb_mac_binding,
                      engine_noop_handler);
 
+    engine_add_input(&en_northd, &en_sb_datapath_binding,
+                     northd_sb_datapath_binding_handler);
     engine_add_input(&en_northd, &en_sb_port_binding,
                      northd_sb_port_binding_handler);
     engine_add_input(&en_northd, &en_nb_logical_switch,
@@ -341,6 +341,10 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
     engine_add_input(&en_northd, &en_port_binding_paired_mirror,
                      engine_noop_handler);
 
+    /* No need for an explicit handler for the SB datapath and
+     * SB IP Multicast changes.*/
+    engine_add_input(&en_northd, &en_sb_ip_multicast, engine_noop_handler);
+
     engine_add_input(&en_lr_nat, &en_northd, lr_nat_northd_handler);
 
     engine_add_input(&en_lr_stateful, &en_northd, lr_stateful_northd_handler);
diff --git a/northd/northd.c b/northd/northd.c
index b700ca28e..3e8cb8981 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -811,8 +811,11 @@ ods_build_array_index(struct ovn_datapaths *datapaths)
      * doesn't matter if they are different on every iteration. */
     size_t index = 0;
 
-    datapaths->array = xrealloc(datapaths->array,
-                            ods_size(datapaths) * sizeof *datapaths->array);
+    datapaths->n_array = ods_size(datapaths);
+    datapaths->n_allocated_array = datapaths->n_array + 10;
+    datapaths->array = xrealloc(
+        datapaths->array,
+        datapaths->n_allocated_array * sizeof *datapaths->array);
 
     struct ovn_datapath *od;
     HMAP_FOR_EACH (od, key_node, &datapaths->datapaths) {
@@ -822,6 +825,23 @@ ods_build_array_index(struct ovn_datapaths *datapaths)
     }
 }
 
+static void
+ods_assign_array_index(struct ovn_datapaths *datapaths,
+                       struct ovn_datapath *od)
+{
+    ovs_assert(ods_size(datapaths) == (datapaths->n_array + 1));
+    od->index = datapaths->n_array;
+
+    if (datapaths->n_array == datapaths->n_allocated_array) {
+        datapaths->n_allocated_array += 10;
+        datapaths->array = xrealloc(
+            datapaths->array,
+            datapaths->n_allocated_array * sizeof *datapaths->array);
+    }
+    datapaths->array[datapaths->n_array++] = od;
+    od->datapaths = datapaths;
+}
+
 /* Initializes 'ls_datapaths' to contain a "struct ovn_datapath" for every
  * logical switch, and initializes 'lr_datapaths' to contain a
  * "struct ovn_datapath" for every logical router.
@@ -4012,6 +4032,12 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn,
     sset_destroy(&active_ha_chassis_grps);
 }
 
+static void
+destroy_tracked_dps(struct tracked_dps *trk_dps)
+{
+    hmapx_clear(&trk_dps->crupdated);
+}
+
 static void
 destroy_tracked_ovn_ports(struct tracked_ovn_ports *trk_ovn_ports)
 {
@@ -4048,6 +4074,7 @@ void
 destroy_northd_data_tracked_changes(struct northd_data *nd)
 {
     struct northd_tracked_data *trk_changes = &nd->trk_data;
+    destroy_tracked_dps(&trk_changes->trk_switches);
     destroy_tracked_ovn_ports(&trk_changes->trk_lsps);
     destroy_tracked_lbs(&trk_changes->trk_lbs);
     hmapx_clear(&trk_changes->trk_nat_lrs);
@@ -4061,6 +4088,7 @@ init_northd_tracked_data(struct northd_data *nd)
 {
     struct northd_tracked_data *trk_data = &nd->trk_data;
     trk_data->type = NORTHD_TRACKED_NONE;
+    hmapx_init(&trk_data->trk_switches.crupdated);
     hmapx_init(&trk_data->trk_lsps.created);
     hmapx_init(&trk_data->trk_lsps.updated);
     hmapx_init(&trk_data->trk_lsps.deleted);
@@ -4076,6 +4104,7 @@ destroy_northd_tracked_data(struct northd_data *nd)
 {
     struct northd_tracked_data *trk_data = &nd->trk_data;
     trk_data->type = NORTHD_TRACKED_NONE;
+    hmapx_destroy(&trk_data->trk_switches.crupdated);
     hmapx_destroy(&trk_data->trk_lsps.created);
     hmapx_destroy(&trk_data->trk_lsps.updated);
     hmapx_destroy(&trk_data->trk_lsps.deleted);
@@ -4524,15 +4553,73 @@ northd_handle_ls_changes(struct ovsdb_idl_txn 
*ovnsb_idl_txn,
                          const struct northd_input *ni,
                          struct northd_data *nd)
 {
-    const struct nbrec_logical_switch *changed_ls;
     struct northd_tracked_data *trk_data = &nd->trk_data;
+    nd->trk_data.type = NORTHD_TRACKED_NONE;
 
-    NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH_TRACKED (changed_ls,
+    /* Loop to handle deleted logical switches. */
+    const struct nbrec_logical_switch *deleted_ls;
+    NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH_TRACKED (deleted_ls,
+                                             ni->nbrec_logical_switch_table) {
+        if (nbrec_logical_switch_is_deleted(deleted_ls)) {
+            goto fail;
+        }
+    }
+
+    /* Loop to handle only newly created logical switches and to
+     * create ovn_datapath objects. */
+    const struct nbrec_logical_switch *new_ls;
+    NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH_TRACKED (new_ls,
                                              ni->nbrec_logical_switch_table) {
-        if (nbrec_logical_switch_is_new(changed_ls) ||
-            nbrec_logical_switch_is_deleted(changed_ls)) {
+        if (!nbrec_logical_switch_is_new(new_ls)) {
+            continue;
+        }
+
+        /* If a logical switch is created with the below columns set,
+         * then we can't handle this yet. Goto fail. */
+        if (new_ls->copp || new_ls->n_dns_records ||
+            new_ls->n_forwarding_groups || new_ls->n_qos_rules) {
             goto fail;
         }
+
+        struct ovn_synced_logical_switch *lsw =
+            datapath_synced_logical_switch_find(ni->synced_lses, new_ls);
+        if (!lsw) {
+            goto fail;
+        }
+
+
+        struct ovn_datapath *od = ovn_datapath_create(
+            &nd->ls_datapaths.datapaths, &new_ls->header_.uuid, new_ls,
+            NULL, lsw->sb);
+
+        ods_assign_array_index(&nd->ls_datapaths, od);
+        init_ipam_info_for_datapath(od);
+        init_mcast_info_for_datapath(od);
+
+        /* Create SB:IP_Multicast for the logical switch. */
+        const struct sbrec_ip_multicast *ip_mcast =
+            sbrec_ip_multicast_insert(ovnsb_idl_txn);
+        store_mcast_info_for_switch_datapath(ip_mcast, od);
+
+        if (!ls_handle_lsp_changes(ovnsb_idl_txn, new_ls,
+                                   ni, nd, od, &trk_data->trk_lsps)) {
+            goto fail;
+        }
+
+        if (new_ls->n_acls) {
+            hmapx_add(&trk_data->ls_with_changed_acls, od);
+        }
+        hmapx_add(&trk_data->trk_switches.crupdated, od);
+    }
+
+    /* Loop to handle updated logical switches. */
+    const struct nbrec_logical_switch *changed_ls;
+    NBREC_LOGICAL_SWITCH_TABLE_FOR_EACH_TRACKED (changed_ls,
+                                             ni->nbrec_logical_switch_table) {
+        if (nbrec_logical_switch_is_new(changed_ls)) {
+            continue;
+        }
+
         struct ovn_datapath *od = ovn_datapath_find_(
                                     &nd->ls_datapaths.datapaths,
                                     &changed_ls->header_.uuid);
@@ -4559,6 +4646,10 @@ northd_handle_ls_changes(struct ovsdb_idl_txn 
*ovnsb_idl_txn,
         }
     }
 
+    if (!hmapx_is_empty(&trk_data->trk_switches.crupdated)) {
+        trk_data->type |= NORTHD_TRACKED_SWITCHES;
+    }
+
     if (!hmapx_is_empty(&trk_data->trk_lsps.created)
         || !hmapx_is_empty(&trk_data->trk_lsps.updated)
         || !hmapx_is_empty(&trk_data->trk_lsps.deleted)) {
@@ -4766,6 +4857,77 @@ fail:
     return false;
 }
 
+bool
+northd_handle_sb_datapath_binding_changes(
+    const struct sbrec_datapath_binding_table *sbrec_dp_table,
+    const struct ovn_datapaths *ls_datapaths,
+    const struct ovn_datapaths *lr_datapaths)
+{
+    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+
+    const struct sbrec_datapath_binding *sbrec_dp;
+    SBREC_DATAPATH_BINDING_TABLE_FOR_EACH_TRACKED (sbrec_dp, sbrec_dp_table) {
+        const char *name = smap_get(&sbrec_dp->external_ids, "name");
+        if (!name) {
+            VLOG_WARN_RL(&rl, "Datapath "UUID_FMT" is present in the"
+                         "Southbound DB without valid external_ids keys",
+                         UUID_ARGS(&sbrec_dp->header_.uuid));
+            return false;
+        }
+
+        struct ovn_datapath *od;
+        if (!strcmp(sbrec_dp->type, "logical-switch")) {
+            od = ovn_datapath_find_(&ls_datapaths->datapaths,
+                                    sbrec_dp->nb_uuid);
+        } else {
+            od = ovn_datapath_find_(&lr_datapaths->datapaths,
+                                    sbrec_dp->nb_uuid);
+        }
+
+        if (!sbrec_datapath_binding_is_deleted(sbrec_dp) && !od) {
+            VLOG_WARN_RL(&rl, "Datapath "UUID_FMT" is present in the "
+                         "Southbound DB with mismatching "
+                         "external-ids:logical-switch/router "UUID_FMT,
+                         UUID_ARGS(&sbrec_dp->header_.uuid),
+                         UUID_ARGS(sbrec_dp->nb_uuid));
+            return false;
+        }
+
+        if (sbrec_datapath_binding_is_new(sbrec_dp)) {
+            if (!od) {
+                VLOG_WARN_RL(&rl, "A datapath-binding for %s is created but "
+                             "the %s is not found.", name, sbrec_dp->type);
+                return false;
+            }
+            od->sb = sbrec_dp;
+        }  else if (sbrec_datapath_binding_is_deleted(sbrec_dp)) {
+            /* Most likely the sbrec_dp was deleted by northd and this is the
+             * notification of that transaction, and we can ignore in this
+             * case. Fallback to recompute otherwise, to avoid dangling
+             * sb idl pointers and other unexpected behavior. */
+            if (od && od->sb == sbrec_dp) {
+                VLOG_WARN_RL(&rl, "A datapath-binding for %s is deleted but "
+                             "the %s still exists.", name, sbrec_dp->type);
+                return false;
+            }
+        } else {
+            /* sbrec_dp is updated.*/
+            if (!od) {
+                VLOG_WARN_RL(&rl, "A datapath-binding for %s is updated but "
+                             "the %s is not found.", name, sbrec_dp->type);
+                return false;
+            }
+            if (od->sb != sbrec_dp) {
+                VLOG_WARN_RL(&rl, "A datapath-binding for %s is updated with "
+                             "a new IDL row, which is unusual.", name);
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
 bool
 northd_handle_sb_port_binding_changes(
     const struct sbrec_port_binding_table *sbrec_port_binding_table,
diff --git a/northd/northd.h b/northd/northd.h
index ac4499ef7..88405665c 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -99,6 +99,8 @@ struct ovn_datapaths {
 
     /* The array index of each element in 'datapaths'. */
     struct ovn_datapath **array;
+    size_t n_array;
+    size_t n_allocated_array;
 };
 
 static inline size_t
@@ -119,6 +121,11 @@ enum redirected_routing_protcol_flag_type {
     REDIRECT_BFD = (1 << 1),
 };
 
+struct tracked_dps {
+    /* Tracked created or updated datapaths. */
+    struct hmapx crupdated;
+};
+
 struct tracked_ovn_ports {
     /* tracked created ports.
      * hmapx node data is 'struct ovn_port *' */
@@ -150,6 +157,7 @@ enum northd_tracked_data_type {
     NORTHD_TRACKED_LR_NATS  = (1 << 2),
     NORTHD_TRACKED_LS_LBS   = (1 << 3),
     NORTHD_TRACKED_LS_ACLS  = (1 << 4),
+    NORTHD_TRACKED_SWITCHES = (1 << 5),
 };
 
 /* Track what's changed in the northd engine node.
@@ -158,6 +166,7 @@ enum northd_tracked_data_type {
 struct northd_tracked_data {
     /* Indicates the type of data tracked.  One or all of NORTHD_TRACKED_*. */
     enum northd_tracked_data_type type;
+    struct tracked_dps trk_switches;
     struct tracked_ovn_ports trk_lsps;
     struct tracked_lbs trk_lbs;
 
@@ -893,6 +902,10 @@ bool lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn 
*,
                                       struct ls_stateful_tracked_data *,
                                       struct lflow_input *,
                                       struct lflow_table *lflows);
+bool northd_handle_sb_datapath_binding_changes(
+    const struct sbrec_datapath_binding_table *,
+    const struct ovn_datapaths *ls_datapaths,
+    const struct ovn_datapaths *lr_datapaths);
 bool northd_handle_sb_port_binding_changes(
     const struct sbrec_port_binding_table *, struct hmap *ls_ports,
     struct hmap *lr_ports);
@@ -962,6 +975,12 @@ northd_has_ls_acls_in_tracked_data(struct 
northd_tracked_data *trk_nd_changes)
     return trk_nd_changes->type & NORTHD_TRACKED_LS_ACLS;
 }
 
+static inline bool
+northd_has_lswitchs_in_tracked_data(struct northd_tracked_data *trk_nd_changes)
+{
+    return trk_nd_changes->type & NORTHD_TRACKED_SWITCHES;
+}
+
 /* Returns 'true' if the IPv4 'addr' is on the same subnet with one of the
  * IPs configured on the router port.
  */
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 33cd8a4ae..a94f01923 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -12595,7 +12595,7 @@ check ovn-nbctl --wait=sb lsp-add sw0 sw0p1 -- 
lsp-set-addresses sw0p1 "00:00:20
 
 check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
 check ovn-nbctl --wait=sb lr-add lr0
-check_engine_stats northd recompute nocompute
+check_engine_stats northd recompute compute
 check_engine_stats lr_nat recompute nocompute
 check_engine_stats lr_stateful recompute nocompute
 check_engine_stats sync_to_sb_pb recompute nocompute
@@ -14656,6 +14656,74 @@ AT_CHECK([grep "lr_in_dnat" lr1flows | 
ovn_strip_lflows | grep "30.0.0.1"], [0],
 AT_CLEANUP
 ])
 
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([Logical switch incremental processing])
+
+ovn_start
+
+net_add n1
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.11
+
+check ovn-sbctl chassis-add gw1 geneve 127.0.0.1
+check ovn-nbctl --wait=sb sync
+
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb ls-add sw0
+check_engine_stats northd norecompute compute
+check_engine_stats ls_stateful recompute compute
+check_engine_stats lflow recompute nocompute
+
+# For the below engine nodes, en_northd is input.  So check
+# their engine status.
+check_engine_stats lr_stateful recompute compute
+check_engine_stats route_policies recompute compute
+check_engine_stats routes recompute compute
+check_engine_stats bfd_sync recompute compute
+check_engine_stats sync_to_sb_lb recompute compute
+check_engine_stats sync_to_sb_pb recompute compute
+
+CHECK_NO_CHANGE_AFTER_RECOMPUTE((1))
+
+# Update the logical switch.
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb set logical_switch sw0 other_config:foo=bar
+
+check_engine_stats northd recompute nocompute
+check_engine_stats ls_stateful recompute nocompute
+check_engine_stats lflow recompute nocompute
+
+# For the below engine nodes, en_northd is input.  So check
+# their engine status.
+check_engine_stats lr_stateful recompute nocompute
+check_engine_stats route_policies recompute nocompute
+check_engine_stats routes recompute nocompute
+check_engine_stats bfd_sync recompute nocompute
+check_engine_stats sync_to_sb_lb recompute nocompute
+check_engine_stats sync_to_sb_pb recompute nocompute
+
+# Delete the logical switch
+check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
+check ovn-nbctl --wait=sb ls-del sw0
+check_engine_stats northd recompute compute
+check_engine_stats ls_stateful recompute nocompute
+check_engine_stats lflow recompute nocompute
+
+# For the below engine nodes, en_northd is input.  So check
+# their engine status.
+check_engine_stats lr_stateful recompute nocompute
+check_engine_stats route_policies recompute nocompute
+check_engine_stats routes recompute nocompute
+check_engine_stats bfd_sync recompute nocompute
+check_engine_stats sync_to_sb_lb recompute nocompute
+check_engine_stats sync_to_sb_pb recompute nocompute
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])
+
 AT_SETUP([RBAC -- Recover builtin role and permissions])
 ovn_start
 
-- 
2.50.0

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

Reply via email to