@@ -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;
+}
@@ -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;
@@ -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) {
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(-)