Add a new type of resource reference handling, from Template_Var to
Load_Balancer.  This is needed to correctly support updating Load_Balancer
flows when the Template_Vars they refer to change.

Signed-off-by: Dumitru Ceara <[email protected]>
---
 controller/lflow.c          |  105 +++++++++++++++++++++++++++++++++----------
 controller/lflow.h          |    7 ++-
 controller/ovn-controller.c |   67 +++++++++++++++++++++------
 lib/lb.c                    |    7 ++-
 lib/lb.h                    |    3 +
 5 files changed, 145 insertions(+), 44 deletions(-)

diff --git a/controller/lflow.c b/controller/lflow.c
index ffc8fdb6e..f59ee69aa 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -97,6 +97,15 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow,
                       struct lflow_ctx_in *l_ctx_in,
                       struct lflow_ctx_out *l_ctx_out);
 
+static void
+consider_lb_hairpin_flows(struct objdep_mgr *mgr,
+                          const struct sbrec_load_balancer *sbrec_lb,
+                          const struct hmap *local_datapaths,
+                          const struct smap *template_vars,
+                          bool use_ct_mark,
+                          struct ovn_desired_flow_table *flow_table,
+                          struct simap *ids);
+
 static void add_port_sec_flows(const struct shash *binding_lports,
                                const struct sbrec_chassis *,
                                struct ovn_desired_flow_table *);
@@ -223,7 +232,7 @@ lflow_handle_changed_flows(struct lflow_ctx_in *l_ctx_in,
         UUIDSET_INITIALIZER(&flood_remove_nodes);
     SBREC_LOGICAL_FLOW_TABLE_FOR_EACH_TRACKED (lflow,
                                                l_ctx_in->logical_flow_table) {
-        if (uuidset_find(l_ctx_out->lflows_processed, &lflow->header_.uuid)) {
+        if (uuidset_find(l_ctx_out->objs_processed, &lflow->header_.uuid)) {
             VLOG_DBG("lflow "UUID_FMT"has been processed, skip.",
                      UUID_ARGS(&lflow->header_.uuid));
             continue;
@@ -252,14 +261,14 @@ lflow_handle_changed_flows(struct lflow_ctx_in *l_ctx_in,
             VLOG_DBG("re-add lflow "UUID_FMT, UUID_ARGS(&lflow->header_.uuid));
 
             /* For the extra lflows that need to be reprocessed because of the
-             * flood remove, remove it from lflows_processed. */
+             * flood remove, remove it from objs_processed. */
             struct uuidset_node *unode =
-                uuidset_find(l_ctx_out->lflows_processed,
+                uuidset_find(l_ctx_out->objs_processed,
                              &lflow->header_.uuid);
             if (unode) {
                 VLOG_DBG("lflow "UUID_FMT"has been processed, now reprocess.",
                          UUID_ARGS(&lflow->header_.uuid));
-                uuidset_delete(l_ctx_out->lflows_processed, unode);
+                uuidset_delete(l_ctx_out->objs_processed, unode);
             }
 
             consider_logical_flow(lflow, false, l_ctx_in, l_ctx_out);
@@ -658,7 +667,7 @@ lflow_handle_addr_set_update(const char *as_name,
     struct object_to_resources_list_node *resource_list_node;
     RESOURCE_FOR_EACH_OBJ (resource_list_node, resource_node) {
         const struct uuid *obj_uuid = &resource_list_node->obj_uuid;
-        if (uuidset_find(l_ctx_out->lflows_processed, obj_uuid)) {
+        if (uuidset_find(l_ctx_out->objs_processed, obj_uuid)) {
             VLOG_DBG("lflow "UUID_FMT"has been processed, skip.",
                      UUID_ARGS(obj_uuid));
             continue;
@@ -748,13 +757,13 @@ lflow_handle_changed_ref(enum objdep_type type, const 
char *res_name,
         }
 
         /* For the extra lflows that need to be reprocessed because of the
-         * flood remove, remove it from lflows_processed. */
+         * flood remove, remove it from objs_processed. */
         struct uuidset_node *unode =
-            uuidset_find(l_ctx_out->lflows_processed, &lflow->header_.uuid);
+            uuidset_find(l_ctx_out->objs_processed, &lflow->header_.uuid);
         if (unode) {
             VLOG_DBG("lflow "UUID_FMT"has been processed, now reprocess.",
                      UUID_ARGS(&lflow->header_.uuid));
-            uuidset_delete(l_ctx_out->lflows_processed, unode);
+            uuidset_delete(l_ctx_out->objs_processed, unode);
         }
 
         consider_logical_flow(lflow, false, l_ctx_in, l_ctx_out);
@@ -762,6 +771,42 @@ lflow_handle_changed_ref(enum objdep_type type, const char 
*res_name,
     uuidset_destroy(&flood_remove_nodes);
 }
 
+void
+lb_handle_changed_ref(enum objdep_type type, const char *res_name,
+                      struct ovs_list *objs_todo,
+                      const void *in_arg, void *out_arg)
+{
+    struct lflow_ctx_in *l_ctx_in = CONST_CAST(struct lflow_ctx_in *, in_arg);
+    struct lflow_ctx_out *l_ctx_out = out_arg;
+
+    struct object_to_resources_list_node *resource_lb_uuid;
+    LIST_FOR_EACH_POP (resource_lb_uuid, list_node, objs_todo) {
+        VLOG_DBG("Reprocess LB "UUID_FMT" for resource type: %s, name: %s",
+                 UUID_ARGS(&resource_lb_uuid->obj_uuid),
+                 objdep_type_name(type), res_name);
+
+        const struct sbrec_load_balancer *lb =
+            sbrec_load_balancer_table_get_for_uuid(
+                l_ctx_in->lb_table, &resource_lb_uuid->obj_uuid);
+        if (!lb) {
+            VLOG_DBG("Failed to find LB "UUID_FMT" referred by: %s",
+                     UUID_ARGS(&resource_lb_uuid->obj_uuid), res_name);
+        } else {
+            ofctrl_remove_flows(l_ctx_out->flow_table,
+                                &resource_lb_uuid->obj_uuid);
+
+            consider_lb_hairpin_flows(l_ctx_out->lb_deps_mgr, lb,
+                                      l_ctx_in->local_datapaths,
+                                      l_ctx_in->template_vars,
+                                      l_ctx_in->lb_hairpin_use_ct_mark,
+                                      l_ctx_out->flow_table,
+                                      l_ctx_out->hairpin_lb_ids);
+        }
+
+        free(resource_lb_uuid);
+    }
+}
+
 static void
 lflow_parse_ctrl_meter(const struct sbrec_logical_flow *lflow,
                        struct ovn_extend_table *meter_table,
@@ -1250,9 +1295,9 @@ consider_logical_flow(const struct sbrec_logical_flow 
*lflow,
 
     COVERAGE_INC(consider_logical_flow);
     if (!is_recompute) {
-        ovs_assert(!uuidset_find(l_ctx_out->lflows_processed,
+        ovs_assert(!uuidset_find(l_ctx_out->objs_processed,
                                  &lflow->header_.uuid));
-        uuidset_insert(l_ctx_out->lflows_processed, &lflow->header_.uuid);
+        uuidset_insert(l_ctx_out->objs_processed, &lflow->header_.uuid);
     }
 
     if (dp) {
@@ -1992,7 +2037,8 @@ add_lb_ct_snat_hairpin_flows(struct ovn_controller_lb *lb,
 }
 
 static void
-consider_lb_hairpin_flows(const struct sbrec_load_balancer *sbrec_lb,
+consider_lb_hairpin_flows(struct objdep_mgr *mgr,
+                          const struct sbrec_load_balancer *sbrec_lb,
                           const struct hmap *local_datapaths,
                           const struct smap *template_vars,
                           bool use_ct_mark,
@@ -2031,8 +2077,9 @@ consider_lb_hairpin_flows(const struct 
sbrec_load_balancer *sbrec_lb,
         return;
     }
 
-    struct ovn_controller_lb *lb = ovn_controller_lb_create(sbrec_lb,
-                                                            template_vars);
+    struct sset template_vars_ref = SSET_INITIALIZER(&template_vars_ref);
+    struct ovn_controller_lb *lb =
+        ovn_controller_lb_create(sbrec_lb, template_vars, &template_vars_ref);
     uint8_t lb_proto = IPPROTO_TCP;
     if (lb->slb->protocol && lb->slb->protocol[0]) {
         if (!strcmp(lb->slb->protocol, "udp")) {
@@ -2042,6 +2089,11 @@ consider_lb_hairpin_flows(const struct 
sbrec_load_balancer *sbrec_lb,
         }
     }
 
+    const char *tv_name;
+    SSET_FOR_EACH (tv_name, &template_vars_ref) {
+        objdep_mgr_add(mgr, OBJDEP_TYPE_TEMPLATE, tv_name,
+                       &sbrec_lb->header_.uuid);
+    }
     for (i = 0; i < lb->n_vips; i++) {
         struct ovn_lb_vip *lb_vip = &lb->vips[i];
 
@@ -2056,12 +2108,14 @@ consider_lb_hairpin_flows(const struct 
sbrec_load_balancer *sbrec_lb,
     add_lb_ct_snat_hairpin_flows(lb, id, lb_proto, flow_table);
 
     ovn_controller_lb_destroy(lb);
+    sset_destroy(&template_vars_ref);
 }
 
 /* Adds OpenFlow flows to flow tables for each Load balancer VIPs and
  * backends to handle the load balanced hairpin traffic. */
 static void
-add_lb_hairpin_flows(const struct sbrec_load_balancer_table *lb_table,
+add_lb_hairpin_flows(struct objdep_mgr *mgr,
+                     const struct sbrec_load_balancer_table *lb_table,
                      const struct hmap *local_datapaths,
                      const struct smap *template_vars,
                      bool use_ct_mark,
@@ -2087,7 +2141,7 @@ add_lb_hairpin_flows(const struct 
sbrec_load_balancer_table *lb_table,
             ovs_assert(id_pool_alloc_id(pool, &id));
             simap_put(ids, lb->name, id);
         }
-        consider_lb_hairpin_flows(lb, local_datapaths, template_vars,
+        consider_lb_hairpin_flows(mgr, lb, local_datapaths, template_vars,
                                   use_ct_mark, flow_table, ids);
     }
 }
@@ -2224,7 +2278,8 @@ lflow_run(struct lflow_ctx_in *l_ctx_in, struct 
lflow_ctx_out *l_ctx_out)
                        l_ctx_in->static_mac_binding_table,
                        l_ctx_in->local_datapaths,
                        l_ctx_out->flow_table);
-    add_lb_hairpin_flows(l_ctx_in->lb_table, l_ctx_in->local_datapaths,
+    add_lb_hairpin_flows(l_ctx_out->lb_deps_mgr, l_ctx_in->lb_table,
+                         l_ctx_in->local_datapaths,
                          l_ctx_in->template_vars,
                          l_ctx_in->lb_hairpin_use_ct_mark,
                          l_ctx_out->flow_table,
@@ -2276,10 +2331,10 @@ lflow_add_flows_for_datapath(const struct 
sbrec_datapath_binding *dp,
     const struct sbrec_logical_flow *lflow;
     SBREC_LOGICAL_FLOW_FOR_EACH_EQUAL (
         lflow, lf_row, l_ctx_in->sbrec_logical_flow_by_logical_datapath) {
-        if (uuidset_find(l_ctx_out->lflows_processed, &lflow->header_.uuid)) {
+        if (uuidset_find(l_ctx_out->objs_processed, &lflow->header_.uuid)) {
             continue;
         }
-        uuidset_insert(l_ctx_out->lflows_processed, &lflow->header_.uuid);
+        uuidset_insert(l_ctx_out->objs_processed, &lflow->header_.uuid);
         consider_logical_flow__(lflow, dp, l_ctx_in, l_ctx_out);
     }
     sbrec_logical_flow_index_destroy_row(lf_row);
@@ -2304,7 +2359,7 @@ lflow_add_flows_for_datapath(const struct 
sbrec_datapath_binding *dp,
         sbrec_logical_flow_index_set_logical_dp_group(lf_row, ldpg);
         SBREC_LOGICAL_FLOW_FOR_EACH_EQUAL (
             lflow, lf_row, l_ctx_in->sbrec_logical_flow_by_logical_dp_group) {
-            if (uuidset_find(l_ctx_out->lflows_processed,
+            if (uuidset_find(l_ctx_out->objs_processed,
                              &lflow->header_.uuid)) {
                 continue;
             }
@@ -2356,7 +2411,8 @@ lflow_add_flows_for_datapath(const struct 
sbrec_datapath_binding *dp,
     /* Add load balancer hairpin flows if the datapath has any load balancers
      * associated. */
     for (size_t i = 0; i < n_dp_lbs; i++) {
-        consider_lb_hairpin_flows(dp_lbs[i], l_ctx_in->local_datapaths,
+        consider_lb_hairpin_flows(l_ctx_out->lb_deps_mgr, dp_lbs[i],
+                                  l_ctx_in->local_datapaths,
                                   l_ctx_in->template_vars,
                                   l_ctx_in->lb_hairpin_use_ct_mark,
                                   l_ctx_out->flow_table,
@@ -2379,7 +2435,7 @@ lflow_handle_flows_for_lport(const struct 
sbrec_port_binding *pb,
                                   OBJDEP_TYPE_PORTBINDING,
                                   pb->logical_port,
                                   lflow_handle_changed_ref,
-                                  l_ctx_out->lflows_processed,
+                                  l_ctx_out->objs_processed,
                                   l_ctx_in, l_ctx_out, &changed)) {
         return false;
     }
@@ -2418,7 +2474,7 @@ lflow_handle_changed_port_bindings(struct lflow_ctx_in 
*l_ctx_in,
                                       OBJDEP_TYPE_PORTBINDING,
                                       pb->logical_port,
                                       lflow_handle_changed_ref,
-                                      l_ctx_out->lflows_processed,
+                                      l_ctx_out->objs_processed,
                                       l_ctx_in, l_ctx_out, &changed)) {
             ret = false;
             break;
@@ -2445,7 +2501,7 @@ lflow_handle_changed_mc_groups(struct lflow_ctx_in 
*l_ctx_in,
         if (!objdep_mgr_handle_change(l_ctx_out->lflow_deps_mgr,
                                       OBJDEP_TYPE_MC_GROUP, ds_cstr(&mg_key),
                                       lflow_handle_changed_ref,
-                                      l_ctx_out->lflows_processed,
+                                      l_ctx_out->objs_processed,
                                       l_ctx_in, l_ctx_out, &changed)) {
             ret = false;
             break;
@@ -2499,7 +2555,8 @@ lflow_handle_changed_lbs(struct lflow_ctx_in *l_ctx_in,
 
         VLOG_DBG("Add load balancer hairpin flows for "UUID_FMT,
                  UUID_ARGS(&lb->header_.uuid));
-        consider_lb_hairpin_flows(lb, l_ctx_in->local_datapaths,
+        consider_lb_hairpin_flows(l_ctx_out->lb_deps_mgr, lb,
+                                  l_ctx_in->local_datapaths,
                                   l_ctx_in->template_vars,
                                   l_ctx_in->lb_hairpin_use_ct_mark,
                                   l_ctx_out->flow_table,
diff --git a/controller/lflow.h b/controller/lflow.h
index 8175bdbea..a1b11a07b 100644
--- a/controller/lflow.h
+++ b/controller/lflow.h
@@ -121,9 +121,10 @@ struct lflow_ctx_out {
     struct ovn_extend_table *group_table;
     struct ovn_extend_table *meter_table;
     struct objdep_mgr *lflow_deps_mgr;
+    struct objdep_mgr *lb_deps_mgr;
     struct lflow_cache *lflow_cache;
     struct conj_ids *conj_ids;
-    struct uuidset *lflows_processed;
+    struct uuidset *objs_processed;
     struct simap *hairpin_lb_ids;
     struct id_pool *hairpin_id_pool;
 };
@@ -173,4 +174,8 @@ bool lflow_handle_changed_mc_groups(struct lflow_ctx_in *,
                                     struct lflow_ctx_out *);
 bool lflow_handle_changed_port_bindings(struct lflow_ctx_in *,
                                         struct lflow_ctx_out *);
+
+void lb_handle_changed_ref(enum objdep_type type, const char *res_name,
+                           struct ovs_list *objs_todo,
+                           const void *in_arg, void *out_arg);
 #endif /* controller/lflow.h */
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 40afebf4e..1731e78b4 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -2805,13 +2805,15 @@ struct ed_type_lflow_output {
     struct ovn_extend_table meter_table;
     /* lflow <-> resource cross reference */
     struct objdep_mgr lflow_deps_mgr;;
+    /* load balancer <-> resource cross reference */
+    struct objdep_mgr lb_deps_mgr;
     /* conjunciton ID usage information of lflows */
     struct conj_ids conj_ids;
 
-    /* lflows processed in the current engine execution.
+    /* objects (lflows and lbs) processed in the current engine execution.
      * Cleared by en_lflow_output_clear_tracked_data before each engine
      * execution. */
-    struct uuidset lflows_processed;
+    struct uuidset objs_processed;
 
     /* Data which is persistent and not cleared during
      * full recompute. */
@@ -2968,8 +2970,9 @@ init_lflow_ctx(struct engine_node *node,
     l_ctx_out->group_table = &fo->group_table;
     l_ctx_out->meter_table = &fo->meter_table;
     l_ctx_out->lflow_deps_mgr = &fo->lflow_deps_mgr;
+    l_ctx_out->lb_deps_mgr = &fo->lb_deps_mgr;
     l_ctx_out->conj_ids = &fo->conj_ids;
-    l_ctx_out->lflows_processed = &fo->lflows_processed;
+    l_ctx_out->objs_processed = &fo->objs_processed;
     l_ctx_out->lflow_cache = fo->pd.lflow_cache;
     l_ctx_out->hairpin_id_pool = fo->hd.pool;
     l_ctx_out->hairpin_lb_ids = &fo->hd.ids;
@@ -2984,8 +2987,9 @@ en_lflow_output_init(struct engine_node *node OVS_UNUSED,
     ovn_extend_table_init(&data->group_table);
     ovn_extend_table_init(&data->meter_table);
     objdep_mgr_init(&data->lflow_deps_mgr);
+    objdep_mgr_init(&data->lb_deps_mgr);
     lflow_conj_ids_init(&data->conj_ids);
-    uuidset_init(&data->lflows_processed);
+    uuidset_init(&data->objs_processed);
     simap_init(&data->hd.ids);
     data->hd.pool = id_pool_create(1, UINT32_MAX - 1);
     nd_ra_opts_init(&data->nd_ra_opts);
@@ -2997,7 +3001,7 @@ static void
 en_lflow_output_clear_tracked_data(void *data)
 {
     struct ed_type_lflow_output *flow_output_data = data;
-    uuidset_clear(&flow_output_data->lflows_processed);
+    uuidset_clear(&flow_output_data->objs_processed);
 }
 
 static void
@@ -3008,8 +3012,9 @@ en_lflow_output_cleanup(void *data)
     ovn_extend_table_destroy(&flow_output_data->group_table);
     ovn_extend_table_destroy(&flow_output_data->meter_table);
     objdep_mgr_destroy(&flow_output_data->lflow_deps_mgr);
+    objdep_mgr_destroy(&flow_output_data->lb_deps_mgr);
     lflow_conj_ids_destroy(&flow_output_data->conj_ids);
-    uuidset_destroy(&flow_output_data->lflows_processed);
+    uuidset_destroy(&flow_output_data->objs_processed);
     lflow_cache_destroy(flow_output_data->pd.lflow_cache);
     simap_destroy(&flow_output_data->hd.ids);
     id_pool_destroy(flow_output_data->hd.pool);
@@ -3044,6 +3049,7 @@ en_lflow_output_run(struct engine_node *node, void *data)
     struct ovn_extend_table *group_table = &fo->group_table;
     struct ovn_extend_table *meter_table = &fo->meter_table;
     struct objdep_mgr *lflow_deps_mgr = &fo->lflow_deps_mgr;
+    struct objdep_mgr *lb_deps_mgr = &fo->lb_deps_mgr;
 
     static bool first_run = true;
     if (first_run) {
@@ -3053,6 +3059,7 @@ en_lflow_output_run(struct engine_node *node, void *data)
         ovn_extend_table_clear(group_table, false /* desired */);
         ovn_extend_table_clear(meter_table, false /* desired */);
         objdep_mgr_clear(lflow_deps_mgr);
+        objdep_mgr_clear(lb_deps_mgr);
         lflow_conj_ids_clear(&fo->conj_ids);
     }
 
@@ -3186,7 +3193,7 @@ lflow_output_addr_sets_handler(struct engine_node *node, 
void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_ADDRSET, ref_name,
                                       lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
@@ -3205,7 +3212,7 @@ lflow_output_addr_sets_handler(struct engine_node *node, 
void *data)
                                           OBJDEP_TYPE_ADDRSET,
                                           shash_node->name,
                                           lflow_handle_changed_ref,
-                                          l_ctx_out.lflows_processed,
+                                          l_ctx_out.objs_processed,
                                           &l_ctx_in, &l_ctx_out, &changed)) {
                 return false;
             }
@@ -3218,7 +3225,7 @@ lflow_output_addr_sets_handler(struct engine_node *node, 
void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_ADDRSET, ref_name,
                                       lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
@@ -3253,7 +3260,7 @@ lflow_output_port_groups_handler(struct engine_node 
*node, void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_PORTGROUP, ref_name,
                                       lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
@@ -3265,7 +3272,7 @@ lflow_output_port_groups_handler(struct engine_node 
*node, void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_PORTGROUP, ref_name,
                                       lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
@@ -3277,7 +3284,7 @@ lflow_output_port_groups_handler(struct engine_node 
*node, void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_PORTGROUP, ref_name,
                                       lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
@@ -3311,7 +3318,17 @@ lflow_output_template_vars_handler(struct engine_node 
*node, void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_TEMPLATE,
                                       res_name, lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
+                                      &l_ctx_in, &l_ctx_out, &changed)) {
+            return false;
+        }
+        if (changed) {
+            engine_set_node_state(node, EN_UPDATED);
+        }
+        if (!objdep_mgr_handle_change(l_ctx_out.lb_deps_mgr,
+                                      OBJDEP_TYPE_TEMPLATE,
+                                      res_name, lb_handle_changed_ref,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
@@ -3323,7 +3340,17 @@ lflow_output_template_vars_handler(struct engine_node 
*node, void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_TEMPLATE,
                                       res_name, lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
+                                      &l_ctx_in, &l_ctx_out, &changed)) {
+            return false;
+        }
+        if (changed) {
+            engine_set_node_state(node, EN_UPDATED);
+        }
+        if (!objdep_mgr_handle_change(l_ctx_out.lb_deps_mgr,
+                                      OBJDEP_TYPE_TEMPLATE,
+                                      res_name, lb_handle_changed_ref,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
@@ -3335,7 +3362,17 @@ lflow_output_template_vars_handler(struct engine_node 
*node, void *data)
         if (!objdep_mgr_handle_change(l_ctx_out.lflow_deps_mgr,
                                       OBJDEP_TYPE_TEMPLATE,
                                       res_name, lflow_handle_changed_ref,
-                                      l_ctx_out.lflows_processed,
+                                      l_ctx_out.objs_processed,
+                                      &l_ctx_in, &l_ctx_out, &changed)) {
+            return false;
+        }
+        if (changed) {
+            engine_set_node_state(node, EN_UPDATED);
+        }
+        if (!objdep_mgr_handle_change(l_ctx_out.lb_deps_mgr,
+                                      OBJDEP_TYPE_TEMPLATE,
+                                      res_name, lb_handle_changed_ref,
+                                      l_ctx_out.objs_processed,
                                       &l_ctx_in, &l_ctx_out, &changed)) {
             return false;
         }
diff --git a/lib/lb.c b/lib/lb.c
index 15cbf29ee..97fdbc227 100644
--- a/lib/lb.c
+++ b/lib/lb.c
@@ -710,7 +710,8 @@ ovn_lb_group_find(const struct hmap *lb_groups, const 
struct uuid *uuid)
 
 struct ovn_controller_lb *
 ovn_controller_lb_create(const struct sbrec_load_balancer *sbrec_lb,
-                         const struct smap *template_vars)
+                         const struct smap *template_vars,
+                         struct sset *template_vars_ref)
 {
     struct ovn_controller_lb *lb = xzalloc(sizeof *lb);
 
@@ -726,10 +727,10 @@ ovn_controller_lb_create(const struct sbrec_load_balancer 
*sbrec_lb,
 
         char *key_s = lexer_parse_template_string(xstrdup(node->key),
                                                   template_vars,
-                                                  NULL);
+                                                  template_vars_ref);
         char *value_s = lexer_parse_template_string(xstrdup(node->value),
                                                     template_vars,
-                                                    NULL);
+                                                    template_vars_ref);
         char *error = ovn_lb_vip_init_explicit(lb_vip, key_s, value_s);
         if (error) {
             free(error);
diff --git a/lib/lb.h b/lib/lb.h
index 265a1215a..9fcbc7923 100644
--- a/lib/lb.h
+++ b/lib/lb.h
@@ -186,7 +186,8 @@ struct ovn_controller_lb {
 
 struct ovn_controller_lb *ovn_controller_lb_create(
     const struct sbrec_load_balancer *,
-    const struct smap *template_vars);
+    const struct smap *template_vars,
+    struct sset *template_vars_ref);
 void ovn_controller_lb_destroy(struct ovn_controller_lb *);
 
 char *ovn_lb_vip_init(struct ovn_lb_vip *lb_vip, const char *lb_key,

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

Reply via email to