[ovs-dev] [PATCH v5 08/20] ovn-controller: Incremental logical flow processing
Han Zhou
zhouhan at gmail.com
Mon Aug 13 17:48:07 UTC 2018
Implements change handler of flow_output for SB lflow changes.
Signed-off-by: Han Zhou <hzhou8 at ebay.com>
---
ovn/controller/lflow.c | 84 +++++++++++++++++++++++++++++++++++++++++
ovn/controller/lflow.h | 18 +++++++++
ovn/controller/ovn-controller.c | 76 ++++++++++++++++++++++++++++++++++++-
3 files changed, 177 insertions(+), 1 deletion(-)
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index 72b1ec7..f7cb6d4 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -200,6 +200,90 @@ add_logical_flows(
nd_ra_opts_destroy(&nd_ra_opts);
}
+bool
+lflow_handle_changed_flows(
+ struct ovsdb_idl_index *sbrec_chassis_by_name,
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct sbrec_dhcp_options_table *dhcp_options_table,
+ const struct sbrec_dhcpv6_options_table *dhcpv6_options_table,
+ const struct sbrec_logical_flow_table *logical_flow_table,
+ const struct hmap *local_datapaths,
+ const struct sbrec_chassis *chassis,
+ const struct shash *addr_sets,
+ const struct shash *port_groups,
+ const struct sset *active_tunnels,
+ const struct sset *local_lport_ids,
+ struct ovn_desired_flow_table *flow_table,
+ struct ovn_extend_table *group_table,
+ struct ovn_extend_table *meter_table,
+ uint32_t *conj_id_ofs)
+{
+ bool ret = true;
+ const struct sbrec_logical_flow *lflow;
+
+ struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts);
+ struct hmap dhcpv6_opts = HMAP_INITIALIZER(&dhcpv6_opts);
+ const struct sbrec_dhcp_options *dhcp_opt_row;
+ SBREC_DHCP_OPTIONS_TABLE_FOR_EACH (dhcp_opt_row, dhcp_options_table) {
+ dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code,
+ dhcp_opt_row->type);
+ }
+
+
+ const struct sbrec_dhcpv6_options *dhcpv6_opt_row;
+ SBREC_DHCPV6_OPTIONS_TABLE_FOR_EACH (dhcpv6_opt_row,
+ dhcpv6_options_table) {
+ dhcp_opt_add(&dhcpv6_opts, dhcpv6_opt_row->name, dhcpv6_opt_row->code,
+ dhcpv6_opt_row->type);
+ }
+
+ struct hmap nd_ra_opts = HMAP_INITIALIZER(&nd_ra_opts);
+ nd_ra_opts_init(&nd_ra_opts);
+
+ /* Handle removed flows first, and then other flows, so that when
+ * the flows being added and removed have same match conditions
+ * can be processed in the proper order */
+ SBREC_LOGICAL_FLOW_TABLE_FOR_EACH_TRACKED (lflow, logical_flow_table) {
+ /* Remove any flows that should be removed. */
+ if (sbrec_logical_flow_is_deleted(lflow)) {
+ VLOG_DBG("handle deleted lflow "UUID_FMT,
+ UUID_ARGS(&lflow->header_.uuid));
+ ofctrl_remove_flows(flow_table, &lflow->header_.uuid);
+ }
+ }
+ SBREC_LOGICAL_FLOW_TABLE_FOR_EACH_TRACKED (lflow, logical_flow_table) {
+ if (!sbrec_logical_flow_is_deleted(lflow)) {
+ /* Now, add/modify existing flows. If the logical
+ * flow is a modification, just remove the flows
+ * for this row, and then add new flows. */
+ if (!sbrec_logical_flow_is_new(lflow)) {
+ VLOG_DBG("handle updated lflow "UUID_FMT,
+ UUID_ARGS(&lflow->header_.uuid));
+ ofctrl_remove_flows(flow_table, &lflow->header_.uuid);
+ }
+ VLOG_DBG("handle new lflow "UUID_FMT,
+ UUID_ARGS(&lflow->header_.uuid));
+ if (!consider_logical_flow(sbrec_chassis_by_name,
+ sbrec_multicast_group_by_name_datapath,
+ sbrec_port_binding_by_name,
+ lflow, local_datapaths,
+ chassis, &dhcp_opts, &dhcpv6_opts,
+ &nd_ra_opts, addr_sets, port_groups,
+ active_tunnels, local_lport_ids,
+ flow_table, group_table, meter_table,
+ conj_id_ofs)) {
+ ret = false;
+ break;
+ }
+ }
+ }
+ dhcp_opts_destroy(&dhcp_opts);
+ dhcp_opts_destroy(&dhcpv6_opts);
+ nd_ra_opts_destroy(&nd_ra_opts);
+ return ret;
+}
+
static bool
update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs)
{
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index b4120d0..31e34e2 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -84,6 +84,24 @@ void lflow_run(struct ovsdb_idl_index *sbrec_chassis_by_name,
struct ovn_extend_table *meter_table,
uint32_t *conj_id_ofs);
+bool lflow_handle_changed_flows(
+ struct ovsdb_idl_index *sbrec_chassis_by_name,
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct sbrec_dhcp_options_table *,
+ const struct sbrec_dhcpv6_options_table *,
+ const struct sbrec_logical_flow_table *,
+ const struct hmap *local_datapaths,
+ const struct sbrec_chassis *,
+ const struct shash *addr_sets,
+ const struct shash *port_groups,
+ const struct sset *active_tunnels,
+ const struct sset *local_lport_ids,
+ struct ovn_desired_flow_table *,
+ struct ovn_extend_table *group_table,
+ struct ovn_extend_table *meter_table,
+ uint32_t *conj_id_ofs);
+
void lflow_destroy(void);
#endif /* ovn/lflow.h */
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index bfe99dd..5c24cba 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -973,6 +973,80 @@ en_flow_output_run(struct engine_node *node)
node->changed = true;
}
+static bool
+flow_output_sb_logical_flow_handler(struct engine_node *node)
+{
+ struct ed_type_runtime_data *data =
+ (struct ed_type_runtime_data *)engine_get_input(
+ "runtime_data", node)->data;
+ struct hmap *local_datapaths = &data->local_datapaths;
+ struct sset *local_lport_ids = &data->local_lport_ids;
+ struct sset *active_tunnels = &data->active_tunnels;
+ struct shash *addr_sets = &data->addr_sets;
+ struct shash *port_groups = &data->port_groups;
+
+ struct ovsrec_open_vswitch_table *ovs_table =
+ (struct ovsrec_open_vswitch_table *)EN_OVSDB_GET(
+ engine_get_input("OVS_open_vswitch", node));
+ struct ovsrec_bridge_table *bridge_table =
+ (struct ovsrec_bridge_table *)EN_OVSDB_GET(
+ engine_get_input("OVS_bridge", node));
+ const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table);
+ const char *chassis_id = get_chassis_id(ovs_table);
+
+ struct ovsdb_idl_index *sbrec_chassis_by_name =
+ engine_ovsdb_node_get_index(
+ engine_get_input("SB_chassis", node),
+ "name");
+ const struct sbrec_chassis *chassis = NULL;
+ if (chassis_id) {
+ chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id);
+ }
+
+ ovs_assert(br_int && chassis);
+
+ struct ed_type_flow_output *fo =
+ (struct ed_type_flow_output *)node->data;
+ struct ovn_desired_flow_table *flow_table = &fo->flow_table;
+ struct ovn_extend_table *group_table = &fo->group_table;
+ struct ovn_extend_table *meter_table = &fo->meter_table;
+ uint32_t *conj_id_ofs = &fo->conj_id_ofs;
+
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath =
+ engine_ovsdb_node_get_index(
+ engine_get_input("SB_multicast_group", node),
+ "name_datapath");
+
+ struct ovsdb_idl_index *sbrec_port_binding_by_name =
+ engine_ovsdb_node_get_index(
+ engine_get_input("SB_port_binding", node),
+ "name");
+
+ struct sbrec_dhcp_options_table *dhcp_table =
+ (struct sbrec_dhcp_options_table *)EN_OVSDB_GET(
+ engine_get_input("SB_dhcp_options", node));
+
+ struct sbrec_dhcpv6_options_table *dhcpv6_table =
+ (struct sbrec_dhcpv6_options_table *)EN_OVSDB_GET(
+ engine_get_input("SB_dhcpv6_options", node));
+
+ struct sbrec_logical_flow_table *logical_flow_table =
+ (struct sbrec_logical_flow_table *)EN_OVSDB_GET(
+ engine_get_input("SB_logical_flow", node));
+
+ bool handled = lflow_handle_changed_flows(sbrec_chassis_by_name,
+ sbrec_multicast_group_by_name_datapath,
+ sbrec_port_binding_by_name,
+ dhcp_table, dhcpv6_table,
+ logical_flow_table,
+ local_datapaths, chassis, addr_sets,
+ port_groups, active_tunnels, local_lport_ids,
+ flow_table, group_table, meter_table, conj_id_ofs);
+
+ node->changed = true;
+ return handled;
+}
+
struct ovn_controller_exit_args {
bool *exiting;
bool *restart;
@@ -1092,7 +1166,7 @@ main(int argc, char *argv[])
engine_add_input(&en_flow_output, &en_sb_datapath_binding, NULL);
engine_add_input(&en_flow_output, &en_sb_port_binding, NULL);
engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL);
- engine_add_input(&en_flow_output, &en_sb_logical_flow, NULL);
+ engine_add_input(&en_flow_output, &en_sb_logical_flow, flow_output_sb_logical_flow_handler);
engine_add_input(&en_flow_output, &en_sb_dhcp_options, NULL);
engine_add_input(&en_flow_output, &en_sb_dhcpv6_options, NULL);
engine_add_input(&en_flow_output, &en_sb_dns, NULL);
--
2.1.0
More information about the dev
mailing list