summaryrefslogtreecommitdiff
path: root/ovn
diff options
context:
space:
mode:
authorHan Zhou <hzhou8@ebay.com>2019-05-17 12:56:29 -0700
committerBen Pfaff <blp@ovn.org>2019-05-24 11:37:29 -0700
commite0b9e339068c02b275631a6c4711ee3c6a918fbf (patch)
tree3513c0ff0a3fbd2a23a04259adfecaeed60d579e /ovn
parent0bd4d85c36efe7bee16569821f9f15b8570f5b3c (diff)
downloadopenvswitch-e0b9e339068c02b275631a6c4711ee3c6a918fbf.tar.gz
ovn-controller: Incremental logical flow processing
Implements change handler of flow_output for SB lflow changes. Signed-off-by: Han Zhou <hzhou8@ebay.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ovn')
-rw-r--r--ovn/controller/lflow.c82
-rw-r--r--ovn/controller/lflow.h17
-rw-r--r--ovn/controller/ovn-controller.c77
3 files changed, 175 insertions, 1 deletions
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index 8712b6dd3..1d7fa8eaa 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -193,6 +193,88 @@ add_logical_flows(
nd_ra_opts_destroy(&nd_ra_opts);
}
+bool
+lflow_handle_changed_flows(
+ 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_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 053c0336c..f9dc11a6b 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -83,6 +83,23 @@ void lflow_run(struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
struct ovn_extend_table *meter_table,
uint32_t *conj_id_ofs);
+bool lflow_handle_changed_flows(
+ 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 711d96a44..881e9d9a3 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -1022,6 +1022,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_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;
@@ -1143,7 +1217,8 @@ main(int argc, char *argv[])
engine_add_input(&en_flow_output, &en_sb_multicast_group, 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);