diff mbox series

[ovs-dev,RFC,3/5] controller: Make resource references more generic.

Message ID 165971684632.246236.5126286132315139482.stgit@dceara.remote.csb
State RFC
Headers show
Series Add OVN component templates. | expand

Commit Message

Dumitru Ceara Aug. 5, 2022, 4:27 p.m. UTC
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
---
TODO:
- Rename resource references to make it clear that they're not only
  about lflows.
---
 controller/lflow.c          |  108 +++++++++++++++++++++++++++----------------
 controller/lflow.h          |   95 ++++++++++++++++++++------------------
 controller/ovn-controller.c |   36 +++++++-------
 3 files changed, 134 insertions(+), 105 deletions(-)
diff mbox series

Patch

diff --git a/controller/lflow.c b/controller/lflow.c
index c1a30b2a4..6e60728f0 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -989,43 +989,12 @@  done:
     return ret;
 }
 
-bool
+static void
 lflow_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,
-                         bool *changed)
+                         struct ovs_list *lflows_todo)
 {
-    struct ref_lflow_node *rlfn =
-        ref_lflow_lookup(&l_ctx_out->lfrr->ref_lflow_table, ref_type,
-                         ref_name);
-    if (!rlfn) {
-        *changed = false;
-        return true;
-    }
-    VLOG_DBG("Handle changed lflow reference for resource type: %d,"
-             " name: %s.", ref_type, ref_name);
-    *changed = false;
-    bool ret = true;
-
-    struct ovs_list lflows_todo = OVS_LIST_INITIALIZER(&lflows_todo);
-
-    struct lflow_ref_list_node *lrln, *lrln_uuid;
-    HMAP_FOR_EACH (lrln, hmap_node, &rlfn->lflow_uuids) {
-        if (lflows_processed_find(l_ctx_out->lflows_processed,
-                                  &lrln->lflow_uuid)) {
-            continue;
-        }
-        /* Use lflow_ref_list_node as list node to store the uuid.
-         * Other fields are not used here. */
-        lrln_uuid = xmalloc(sizeof *lrln_uuid);
-        lrln_uuid->lflow_uuid = lrln->lflow_uuid;
-        ovs_list_push_back(&lflows_todo, &lrln_uuid->list_node);
-    }
-    if (ovs_list_is_empty(&lflows_todo)) {
-        return true;
-    }
-    *changed = true;
-
     struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts);
     struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts);
     const struct sbrec_dhcp_options *dhcp_opt_row;
@@ -1050,8 +1019,9 @@  lflow_handle_changed_ref(enum ref_type ref_type, const char *ref_name,
 
     /* Re-parse the related lflows. */
     /* Firstly, flood remove the flows from desired flow table. */
+    struct lflow_ref_list_node *lrln_uuid;
     struct hmap flood_remove_nodes = HMAP_INITIALIZER(&flood_remove_nodes);
-    LIST_FOR_EACH_SAFE (lrln_uuid, list_node, &lflows_todo) {
+    LIST_FOR_EACH_SAFE (lrln_uuid, list_node, lflows_todo) {
         VLOG_DBG("Reprocess lflow "UUID_FMT" for resource type: %d,"
                  " name: %s.",
                  UUID_ARGS(&lrln_uuid->lflow_uuid),
@@ -1104,7 +1074,6 @@  lflow_handle_changed_ref(enum ref_type ref_type, const char *ref_name,
     dhcp_opts_destroy(&dhcpv6_opts);
     nd_ra_opts_destroy(&nd_ra_opts);
     controller_event_opts_destroy(&controller_event_opts);
-    return ret;
 }
 
 static void
@@ -2769,8 +2738,8 @@  lflow_handle_flows_for_lport(const struct sbrec_port_binding *pb,
 {
     bool changed;
 
-    if (!lflow_handle_changed_ref(REF_TYPE_PORTBINDING, pb->logical_port,
-                                  l_ctx_in, l_ctx_out, &changed)) {
+    if (!ref_change_handle(REF_TYPE_PORTBINDING, pb->logical_port,
+                           l_ctx_in, l_ctx_out, &changed)) {
         return false;
     }
 
@@ -2804,8 +2773,8 @@  lflow_handle_changed_port_bindings(struct lflow_ctx_in *l_ctx_in,
             && !sbrec_port_binding_is_deleted(pb)) {
             continue;
         }
-        if (!lflow_handle_changed_ref(REF_TYPE_PORTBINDING, pb->logical_port,
-                                      l_ctx_in, l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_PORTBINDING, pb->logical_port,
+                               l_ctx_in, l_ctx_out, &changed)) {
             ret = false;
             break;
         }
@@ -2828,8 +2797,8 @@  lflow_handle_changed_mc_groups(struct lflow_ctx_in *l_ctx_in,
             && !sbrec_multicast_group_is_deleted(mg)) {
             continue;
         }
-        if (!lflow_handle_changed_ref(REF_TYPE_MC_GROUP, ds_cstr(&mg_key),
-                                      l_ctx_in, l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_MC_GROUP, ds_cstr(&mg_key),
+                               l_ctx_in, l_ctx_out, &changed)) {
             ret = false;
             break;
         }
@@ -3699,3 +3668,60 @@  consider_port_sec_flows(const struct sbrec_port_binding *pb,
     }
     free(ps_addrs);
 }
+
+/* Allow potentially different reference change handlers per type. */
+typedef void (*ref_change_handler)(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 *ref_nodes);
+
+static ref_change_handler ref_change_handlers[REF_TYPE_MAX] = {
+    [REF_TYPE_ADDRSET] = lflow_handle_changed_ref,
+    [REF_TYPE_PORTGROUP] = lflow_handle_changed_ref,
+    [REF_TYPE_PORTBINDING] = lflow_handle_changed_ref,
+    [REF_TYPE_MC_GROUP] = lflow_handle_changed_ref,
+    [REF_TYPE_TEMPLATE] = lflow_handle_changed_ref,
+};
+
+bool
+ref_change_handle(enum ref_type ref_type, const char *ref_name,
+                  struct lflow_ctx_in *l_ctx_in,
+                  struct lflow_ctx_out *l_ctx_out,
+                  bool *changed)
+{
+    struct ref_lflow_node *rlfn =
+        ref_lflow_lookup(&l_ctx_out->lfrr->ref_lflow_table, ref_type,
+                         ref_name);
+    if (!rlfn) {
+        *changed = false;
+        return true;
+    }
+    VLOG_DBG("Handle changed lflow reference for resource type: %d,"
+             " name: %s.", ref_type, ref_name);
+    *changed = false;
+
+    struct ovs_list lflows_todo = OVS_LIST_INITIALIZER(&lflows_todo);
+
+    struct lflow_ref_list_node *lrln, *lrln_uuid;
+    HMAP_FOR_EACH (lrln, hmap_node, &rlfn->lflow_uuids) {
+        if (lflows_processed_find(l_ctx_out->lflows_processed,
+                                  &lrln->lflow_uuid)) {
+            continue;
+        }
+        /* Use lflow_ref_list_node as list node to store the uuid.
+         * Other fields are not used here. */
+        lrln_uuid = xmalloc(sizeof *lrln_uuid);
+        lrln_uuid->lflow_uuid = lrln->lflow_uuid;
+        ovs_list_push_back(&lflows_todo, &lrln_uuid->list_node);
+    }
+    if (ovs_list_is_empty(&lflows_todo)) {
+        return true;
+    }
+    *changed = true;
+
+    /* This takes ownership of lflows_todo. */
+    ref_change_handlers[ref_type](ref_type, ref_name, l_ctx_in, l_ctx_out,
+                                  &lflows_todo);
+    return true;
+}
diff --git a/controller/lflow.h b/controller/lflow.h
index d4480c2a2..21e682017 100644
--- a/controller/lflow.h
+++ b/controller/lflow.h
@@ -80,14 +80,63 @@  struct uuid;
 #define OFTABLE_CHK_IN_PORT_SEC_ND   74
 #define OFTABLE_CHK_OUT_PORT_SEC     75
 
+struct lflow_ctx_in {
+    struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath;
+    struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath;
+    struct ovsdb_idl_index *sbrec_logical_flow_by_logical_dp_group;
+    struct ovsdb_idl_index *sbrec_port_binding_by_name;
+    struct ovsdb_idl_index *sbrec_fdb_by_dp_key;
+    struct ovsdb_idl_index *sbrec_mac_binding_by_datapath;
+    struct ovsdb_idl_index *sbrec_static_mac_binding_by_datapath;
+    const struct sbrec_port_binding_table *port_binding_table;
+    const struct sbrec_dhcp_options_table *dhcp_options_table;
+    const struct sbrec_dhcpv6_options_table *dhcpv6_options_table;
+    const struct sbrec_datapath_binding_table *dp_binding_table;
+    const struct sbrec_mac_binding_table *mac_binding_table;
+    const struct sbrec_logical_flow_table *logical_flow_table;
+    const struct sbrec_logical_dp_group_table *logical_dp_group_table;
+    const struct sbrec_multicast_group_table *mc_group_table;
+    const struct sbrec_fdb_table *fdb_table;
+    const struct sbrec_chassis *chassis;
+    const struct sbrec_load_balancer_table *lb_table;
+    const struct sbrec_static_mac_binding_table *static_mac_binding_table;
+    const struct hmap *local_datapaths;
+    const struct shash *addr_sets;
+    const struct shash *port_groups;
+    const struct sset *active_tunnels;
+    const struct sset *related_lport_ids;
+    const struct shash *binding_lports;
+    const struct hmap *chassis_tunnels;
+    const struct smap *template_vars;
+    bool lb_hairpin_use_ct_mark;
+};
+
+struct lflow_ctx_out {
+    struct ovn_desired_flow_table *flow_table;
+    struct ovn_extend_table *group_table;
+    struct ovn_extend_table *meter_table;
+    struct lflow_resource_ref *lfrr;
+    struct lflow_cache *lflow_cache;
+    struct conj_ids *conj_ids;
+    struct hmap *lflows_processed;
+    struct simap *hairpin_lb_ids;
+    struct id_pool *hairpin_id_pool;
+};
+
 enum ref_type {
     REF_TYPE_ADDRSET,
     REF_TYPE_PORTGROUP,
     REF_TYPE_PORTBINDING,
     REF_TYPE_MC_GROUP,
     REF_TYPE_TEMPLATE,
+    REF_TYPE_MAX,
 };
 
+bool ref_change_handle(enum ref_type ref_type, const char *ref_name,
+                       struct lflow_ctx_in *l_ctx_in,
+                       struct lflow_ctx_out *l_ctx_out,
+                       bool *changed);
+
 struct ref_lflow_node {
     struct hmap_node node; /* node in lflow_resource_ref.ref_lflow_table. */
     enum ref_type type; /* key */
@@ -134,49 +183,6 @@  void lflow_resource_init(struct lflow_resource_ref *);
 void lflow_resource_destroy(struct lflow_resource_ref *);
 void lflow_resource_clear(struct lflow_resource_ref *);
 
-struct lflow_ctx_in {
-    struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath;
-    struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath;
-    struct ovsdb_idl_index *sbrec_logical_flow_by_logical_dp_group;
-    struct ovsdb_idl_index *sbrec_port_binding_by_name;
-    struct ovsdb_idl_index *sbrec_fdb_by_dp_key;
-    struct ovsdb_idl_index *sbrec_mac_binding_by_datapath;
-    struct ovsdb_idl_index *sbrec_static_mac_binding_by_datapath;
-    const struct sbrec_port_binding_table *port_binding_table;
-    const struct sbrec_dhcp_options_table *dhcp_options_table;
-    const struct sbrec_dhcpv6_options_table *dhcpv6_options_table;
-    const struct sbrec_datapath_binding_table *dp_binding_table;
-    const struct sbrec_mac_binding_table *mac_binding_table;
-    const struct sbrec_logical_flow_table *logical_flow_table;
-    const struct sbrec_logical_dp_group_table *logical_dp_group_table;
-    const struct sbrec_multicast_group_table *mc_group_table;
-    const struct sbrec_fdb_table *fdb_table;
-    const struct sbrec_chassis *chassis;
-    const struct sbrec_load_balancer_table *lb_table;
-    const struct sbrec_static_mac_binding_table *static_mac_binding_table;
-    const struct hmap *local_datapaths;
-    const struct shash *addr_sets;
-    const struct shash *port_groups;
-    const struct sset *active_tunnels;
-    const struct sset *related_lport_ids;
-    const struct shash *binding_lports;
-    const struct hmap *chassis_tunnels;
-    const struct smap *template_vars;
-    bool lb_hairpin_use_ct_mark;
-};
-
-struct lflow_ctx_out {
-    struct ovn_desired_flow_table *flow_table;
-    struct ovn_extend_table *group_table;
-    struct ovn_extend_table *meter_table;
-    struct lflow_resource_ref *lfrr;
-    struct lflow_cache *lflow_cache;
-    struct conj_ids *conj_ids;
-    struct hmap *lflows_processed;
-    struct simap *hairpin_lb_ids;
-    struct id_pool *hairpin_id_pool;
-};
-
 struct lflow_processed_node {
     struct hmap_node hmap_node; /* In ed_type_lflow_output.lflows_processed. */
     struct uuid lflow_uuid;
@@ -188,9 +194,6 @@  void lflow_run(struct lflow_ctx_in *, struct lflow_ctx_out *);
 void lflow_handle_cached_flows(struct lflow_cache *,
                                const struct sbrec_logical_flow_table *);
 bool lflow_handle_changed_flows(struct lflow_ctx_in *, struct lflow_ctx_out *);
-bool lflow_handle_changed_ref(enum ref_type, const char *ref_name,
-                              struct lflow_ctx_in *, struct lflow_ctx_out *,
-                              bool *changed);
 
 struct addr_set_diff {
     struct expr_constant_set *added;
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 1fe0efa2b..207ea4e51 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -2957,8 +2957,8 @@  lflow_output_addr_sets_handler(struct engine_node *node, void *data)
     }
 
     SSET_FOR_EACH (ref_name, &as_data->deleted) {
-        if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_ADDRSET, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {
@@ -2972,8 +2972,8 @@  lflow_output_addr_sets_handler(struct engine_node *node, void *data)
                                           &l_ctx_out, &changed)) {
             VLOG_DBG("Can't incrementally handle the change of address set %s."
                      " Reprocess related lflows.", shash_node->name);
-            if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, shash_node->name,
-                                          &l_ctx_in, &l_ctx_out, &changed)) {
+            if (!ref_change_handle(REF_TYPE_ADDRSET, shash_node->name,
+                                   &l_ctx_in, &l_ctx_out, &changed)) {
                 return false;
             }
         }
@@ -2982,8 +2982,8 @@  lflow_output_addr_sets_handler(struct engine_node *node, void *data)
         }
     }
     SSET_FOR_EACH (ref_name, &as_data->new) {
-        if (!lflow_handle_changed_ref(REF_TYPE_ADDRSET, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_ADDRSET, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {
@@ -3014,8 +3014,8 @@  lflow_output_port_groups_handler(struct engine_node *node, void *data)
     }
 
     SSET_FOR_EACH (ref_name, &pg_data->deleted) {
-        if (!lflow_handle_changed_ref(REF_TYPE_PORTGROUP, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_PORTGROUP, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {
@@ -3023,8 +3023,8 @@  lflow_output_port_groups_handler(struct engine_node *node, void *data)
         }
     }
     SSET_FOR_EACH (ref_name, &pg_data->updated) {
-        if (!lflow_handle_changed_ref(REF_TYPE_PORTGROUP, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_PORTGROUP, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {
@@ -3032,8 +3032,8 @@  lflow_output_port_groups_handler(struct engine_node *node, void *data)
         }
     }
     SSET_FOR_EACH (ref_name, &pg_data->new) {
-        if (!lflow_handle_changed_ref(REF_TYPE_PORTGROUP, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_PORTGROUP, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {
@@ -3064,8 +3064,8 @@  lflow_output_template_vars_handler(struct engine_node *node, void *data)
     }
 
     SSET_FOR_EACH (ref_name, &tv_data->deleted) {
-        if (!lflow_handle_changed_ref(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {
@@ -3073,8 +3073,8 @@  lflow_output_template_vars_handler(struct engine_node *node, void *data)
         }
     }
     SSET_FOR_EACH (ref_name, &tv_data->updated) {
-        if (!lflow_handle_changed_ref(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {
@@ -3082,8 +3082,8 @@  lflow_output_template_vars_handler(struct engine_node *node, void *data)
         }
     }
     SSET_FOR_EACH (ref_name, &tv_data->new) {
-        if (!lflow_handle_changed_ref(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
-                                      &l_ctx_out, &changed)) {
+        if (!ref_change_handle(REF_TYPE_TEMPLATE, ref_name, &l_ctx_in,
+                               &l_ctx_out, &changed)) {
             return false;
         }
         if (changed) {