Signed-off-by: Dumitru Ceara <[email protected]>
---
 controller/lflow.c          |   72 ++++++++++++++++++++++++++++++++++++++-----
 controller/lflow.h          |    1 +
 controller/ovn-controller.c |   21 +++++++++++++
 lib/lb.c                    |    7 ++--
 lib/lb.h                    |    3 +-
 5 files changed, 92 insertions(+), 12 deletions(-)

diff --git a/controller/lflow.c b/controller/lflow.c
index fe887d3cb..f3ec5528e 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -54,6 +54,7 @@ lflow_init(void)
 {
     ovn_init_symtab(&symtab);
 }
+
 
 struct lookup_port_aux {
     struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath;
@@ -98,6 +99,14 @@ consider_logical_flow(const struct sbrec_logical_flow *lflow,
                       bool is_recompute,
                       struct lflow_ctx_in *l_ctx_in,
                       struct lflow_ctx_out *l_ctx_out);
+static void
+consider_lb_hairpin_flows(struct lflow_resource_ref *lfrr,
+                          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 struct lflow_processed_node *
 lflows_processed_find(struct hmap *lflows_processed,
                       const struct uuid *lflow_uuid);
@@ -1076,6 +1085,40 @@ lflow_handle_changed_ref(enum ref_type ref_type, const 
char *ref_name,
     controller_event_opts_destroy(&controller_event_opts);
 }
 
+static void
+lb_handle_changed_ref(enum ref_type ref_type, const char *ref_name,
+                      struct lflow_ctx_in *l_ctx_in,
+                      struct lflow_ctx_out *l_ctx_out,
+                      struct ovs_list *lbs_todo)
+{
+    struct lflow_ref_list_node *lrln_uuid;
+    LIST_FOR_EACH_POP (lrln_uuid, list_node, lbs_todo) {
+        VLOG_DBG("Reprocess LB "UUID_FMT" for resource type: %d,"
+                 " name: %s",
+                 UUID_ARGS(&lrln_uuid->lflow_uuid),
+                 ref_type, ref_name);
+
+        const struct sbrec_load_balancer *lb =
+            sbrec_load_balancer_table_get_for_uuid(l_ctx_in->lb_table,
+                                                   &lrln_uuid->lflow_uuid);
+        if (!lb) {
+            VLOG_DBG("Failed to find LB "UUID_FMT" referred by: %s",
+                     UUID_ARGS(&lrln_uuid->lflow_uuid), ref_name);
+        } else {
+            ofctrl_remove_flows(l_ctx_out->flow_table, &lrln_uuid->lflow_uuid);
+
+            consider_lb_hairpin_flows(l_ctx_out->lfrr, 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(lrln_uuid);
+    }
+}
+
 static void
 lflow_parse_ctrl_meter(const struct sbrec_logical_flow *lflow,
                        struct ovn_extend_table *meter_table,
@@ -2342,7 +2385,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 lflow_resource_ref *lfrr,
+                          const struct sbrec_load_balancer *sbrec_lb,
                           const struct hmap *local_datapaths,
                           const struct smap *template_vars,
                           bool use_ct_mark,
@@ -2368,8 +2412,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")) {
@@ -2379,6 +2424,11 @@ consider_lb_hairpin_flows(const struct 
sbrec_load_balancer *sbrec_lb,
         }
     }
 
+    const char *tv_name;
+    SSET_FOR_EACH (tv_name, &template_vars_ref) {
+        lflow_resource_add(lfrr, REF_TYPE_TEMPLATE_LB, tv_name,
+                           &sbrec_lb->header_.uuid, 0);
+    }
     for (i = 0; i < lb->n_vips; i++) {
         struct ovn_lb_vip *lb_vip = &lb->vips[i];
 
@@ -2393,12 +2443,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 lflow_resource_ref *lfrr,
+                     const struct sbrec_load_balancer_table *lb_table,
                      const struct hmap *local_datapaths,
                      const struct smap *template_vars,
                      bool use_ct_mark,
@@ -2424,7 +2476,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(lfrr, lb, local_datapaths, template_vars,
                                   use_ct_mark, flow_table, ids);
     }
 }
@@ -2561,7 +2613,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->lfrr, 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,
@@ -2726,7 +2779,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->lfrr, 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,
@@ -2858,7 +2912,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->lfrr, lb,
+                                  l_ctx_in->local_datapaths,
                                   l_ctx_in->template_vars,
                                   l_ctx_in->lb_hairpin_use_ct_mark,
                                   l_ctx_out->flow_table,
@@ -3690,6 +3745,7 @@ static ref_change_handler 
ref_change_handlers[REF_TYPE_MAX] = {
     [REF_TYPE_PORTBINDING] = lflow_handle_changed_ref,
     [REF_TYPE_MC_GROUP] = lflow_handle_changed_ref,
     [REF_TYPE_TEMPLATE] = lflow_handle_changed_ref,
+    [REF_TYPE_TEMPLATE_LB] = lb_handle_changed_ref,
 };
 
 bool
diff --git a/controller/lflow.h b/controller/lflow.h
index 21e682017..aa08d911d 100644
--- a/controller/lflow.h
+++ b/controller/lflow.h
@@ -129,6 +129,7 @@ enum ref_type {
     REF_TYPE_PORTBINDING,
     REF_TYPE_MC_GROUP,
     REF_TYPE_TEMPLATE,
+    REF_TYPE_TEMPLATE_LB,
     REF_TYPE_MAX,
 };
 
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 207ea4e51..0f33dac9e 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -3071,6 +3071,13 @@ lflow_output_template_vars_handler(struct engine_node 
*node, void *data)
         if (changed) {
             engine_set_node_state(node, EN_UPDATED);
         }
+        if (!ref_change_handle(REF_TYPE_TEMPLATE_LB, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
+            return false;
+        }
+        if (changed) {
+            engine_set_node_state(node, EN_UPDATED);
+        }
     }
     SSET_FOR_EACH (ref_name, &tv_data->updated) {
         if (!ref_change_handle(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
@@ -3080,6 +3087,13 @@ lflow_output_template_vars_handler(struct engine_node 
*node, void *data)
         if (changed) {
             engine_set_node_state(node, EN_UPDATED);
         }
+        if (!ref_change_handle(REF_TYPE_TEMPLATE_LB, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
+            return false;
+        }
+        if (changed) {
+            engine_set_node_state(node, EN_UPDATED);
+        }
     }
     SSET_FOR_EACH (ref_name, &tv_data->new) {
         if (!ref_change_handle(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
@@ -3089,6 +3103,13 @@ lflow_output_template_vars_handler(struct engine_node 
*node, void *data)
         if (changed) {
             engine_set_node_state(node, EN_UPDATED);
         }
+        if (!ref_change_handle(REF_TYPE_TEMPLATE_LB, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
+            return false;
+        }
+        if (changed) {
+            engine_set_node_state(node, EN_UPDATED);
+        }
     }
 
     return true;
diff --git a/lib/lb.c b/lib/lb.c
index 56944ace8..a81de7ca6 100644
--- a/lib/lb.c
+++ b/lib/lb.c
@@ -413,7 +413,8 @@ ovn_northd_lb_destroy(struct ovn_northd_lb *lb)
 
 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);
 
@@ -429,10 +430,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);
         if (ovn_lb_vip_init_explicit(lb_vip, key_s, value_s)) {
             n_vips++;
         }
diff --git a/lib/lb.h b/lib/lb.h
index 192ec7ed2..99146b6ab 100644
--- a/lib/lb.h
+++ b/lib/lb.h
@@ -126,7 +126,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 *);
 
 #endif /* OVN_LIB_LB_H 1 */

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

Reply via email to