This allows upcoming patches to initialize the I-P engine from different places in ovn-controller.
Signed-off-by: Dumitru Ceara <[email protected]> --- controller/ovn-controller.c | 1097 ++++++++++++++++++----------------- 1 file changed, 569 insertions(+), 528 deletions(-) diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index f9f2172768..52fc69f31f 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -6581,260 +6581,612 @@ static ENGINE_NODE(evpn_vtep_binding, CLEAR_TRACKED_DATA); static ENGINE_NODE(evpn_fdb, CLEAR_TRACKED_DATA); static ENGINE_NODE(evpn_arp, CLEAR_TRACKED_DATA); -/* Returns false if the northd internal version stored in SB_Global - * and ovn-controller internal version don't match. - */ -static bool -check_northd_version(struct ovsdb_idl *ovs_idl, struct ovsdb_idl *ovnsb_idl, - const char *version) -{ - static bool version_mismatch; +static void +inc_proc_ovn_controller_init( + struct ovsdb_idl_loop *sb_idl_loop, struct ovsdb_idl_loop *ovs_idl_loop, + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_port_binding_by_name, + struct ovsdb_idl_index *sbrec_port_binding_by_key, + struct ovsdb_idl_index *sbrec_datapath_binding_by_key, + struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip, + struct ovsdb_idl_index *ovsrec_flow_sample_collector_set_by_id, + struct ovsdb_idl_index *ovsrec_port_by_qos, + struct ovsdb_idl_index *ovsrec_interface_by_name, + struct ovsdb_idl_index *ovsrec_queue_by_external_ids) +{ + /* Define relationships between nodes where first argument is dependent + * on the second argument. */ - const struct ovsrec_open_vswitch *cfg = ovsrec_open_vswitch_first(ovs_idl); - const struct ovsrec_open_vswitch_table *ovs_table = - ovsrec_open_vswitch_table_get(ovs_idl); - const char *chassis_id = get_ovs_chassis_id(ovs_table); - if (!cfg || !get_chassis_external_id_value_bool( - &cfg->external_ids, chassis_id, - "ovn-match-northd-version", false)) { - version_mismatch = false; - return true; - } + engine_add_input(&en_template_vars, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_template_vars, &en_sb_chassis, NULL); + engine_add_input(&en_template_vars, &en_sb_chassis_template_var, + template_vars_sb_chassis_template_var_handler); - const struct sbrec_sb_global *sb = sbrec_sb_global_first(ovnsb_idl); - if (!sb) { - version_mismatch = true; - return false; - } + engine_add_input(&en_lb_data, &en_sb_load_balancer, + lb_data_sb_load_balancer_handler); + engine_add_input(&en_lb_data, &en_template_vars, + lb_data_template_var_handler); + engine_add_input(&en_lb_data, &en_runtime_data, + lb_data_runtime_data_handler); - const char *northd_version = - smap_get_def(&sb->options, "northd_internal_version", ""); + engine_add_input(&en_route, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_route, &en_sb_chassis, NULL); + engine_add_input(&en_route, &en_sb_port_binding, + route_sb_port_binding_data_handler); + engine_add_input(&en_route, &en_runtime_data, + route_runtime_data_handler); + engine_add_input(&en_route, &en_sb_advertised_route, + route_sb_advertised_route_data_handler); - if (strcmp(northd_version, version)) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); - VLOG_WARN_RL(&rl, "controller version - %s mismatch with northd " - "version - %s", version, northd_version); - version_mismatch = true; - return false; - } + engine_add_input(&en_route_exchange, &en_route, NULL); + engine_add_input(&en_route_exchange, &en_sb_learned_route, + engine_noop_handler); + engine_add_input(&en_route_exchange, &en_sb_port_binding, + engine_noop_handler); + engine_add_input(&en_route_exchange, &en_route_table_notify, NULL); + engine_add_input(&en_route_exchange, &en_route_exchange_status, NULL); + engine_add_input(&en_route_exchange, &en_sb_ro, + route_exchange_sb_ro_handler); - /* If there used to be a mismatch and ovn-northd got updated, force a - * full recompute. + engine_add_input(&en_addr_sets, &en_sb_address_set, + addr_sets_sb_address_set_handler); + engine_add_input(&en_port_groups, &en_sb_port_group, + port_groups_sb_port_group_handler); + /* port_groups computation requires runtime_data's lbinding_data for the + * locally bound ports. */ + engine_add_input(&en_port_groups, &en_runtime_data, + port_groups_runtime_data_handler); + + engine_add_input(&en_non_vif_data, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_non_vif_data, &en_ovs_bridge, NULL); + engine_add_input(&en_non_vif_data, &en_sb_chassis, NULL); + engine_add_input(&en_non_vif_data, &en_ovs_interface, + non_vif_data_ovs_iface_handler); + + engine_add_input(&en_if_status_mgr, &en_ovs_interface, + if_status_mgr_ovs_interface_handler); + engine_add_input(&en_bfd_chassis, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_bfd_chassis, &en_sb_chassis, NULL); + engine_add_input(&en_bfd_chassis, &en_sb_ha_chassis_group, NULL); + + /* Note: The order of inputs is important, all OVS interface changes must + * be handled before any ct_zone changes. */ - if (version_mismatch) { - engine_set_force_recompute(); - } - version_mismatch = false; - return true; -} + engine_add_input(&en_pflow_output, &en_non_vif_data, + NULL); + engine_add_input(&en_pflow_output, &en_northd_options, NULL); + engine_add_input(&en_pflow_output, &en_ct_zones, + pflow_output_ct_zones_handler); + engine_add_input(&en_pflow_output, &en_sb_chassis, + pflow_lflow_output_sb_chassis_handler); -static void -br_int_remote_update(struct br_int_remote *remote, - const struct ovsrec_bridge *br_int, - const struct ovsrec_open_vswitch_table *ovs_table) -{ - if (!br_int) { - return; - } + engine_add_input(&en_pflow_output, &en_if_status_mgr, + pflow_output_if_status_mgr_handler); + engine_add_input(&en_pflow_output, &en_sb_port_binding, + pflow_output_sb_port_binding_handler); + engine_add_input(&en_pflow_output, &en_sb_multicast_group, + pflow_output_sb_multicast_group_handler); - const struct ovsrec_open_vswitch *cfg = - ovsrec_open_vswitch_table_first(ovs_table); + /* pflow_output needs to access the SB datapath binding and hence a noop + * handler. + */ + engine_add_input(&en_pflow_output, &en_sb_datapath_binding, + engine_noop_handler); + engine_add_input(&en_pflow_output, &en_activated_ports, + pflow_output_activated_ports_handler); - const char *ext_target = - smap_get(&cfg->external_ids, "ovn-bridge-remote"); - char *target = ext_target - ? xstrdup(ext_target) - : xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name); + engine_add_input(&en_pflow_output, &en_runtime_data, + pflow_output_runtime_data_handler); + engine_add_input(&en_pflow_output, &en_sb_encap, NULL); + engine_add_input(&en_pflow_output, &en_mff_ovn_geneve, NULL); + engine_add_input(&en_pflow_output, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_pflow_output, &en_ovs_bridge, NULL); + engine_add_input(&en_pflow_output, &en_ovs_flow_sample_collector_set, + pflow_output_debug_handler); + engine_add_input(&en_pflow_output, &en_sb_sb_global, + pflow_output_debug_handler); - if (!remote->target || strcmp(remote->target, target)) { - free(remote->target); - remote->target = target; - } else { - free(target); - } + engine_add_input(&en_northd_options, &en_sb_sb_global, + en_northd_options_sb_sb_global_handler); - unsigned long long probe_interval = - smap_get_ullong(&cfg->external_ids, - "ovn-bridge-remote-probe-interval", 0); - remote->probe_interval = MIN(probe_interval / 1000, INT_MAX); -} + engine_add_input(&en_dhcp_options, &en_sb_dhcp_options, NULL); + engine_add_input(&en_dhcp_options, &en_sb_dhcpv6_options, NULL); -static void -ovsdb_idl_loop_next_cfg_inc(struct ovsdb_idl_loop *idl_loop) -{ - if (idl_loop->next_cfg == INT64_MAX) { - idl_loop->next_cfg = 0; - } else { - idl_loop->next_cfg++; - } -} + engine_add_input(&en_lflow_output, &en_northd_options, NULL); + engine_add_input(&en_lflow_output, &en_dhcp_options, NULL); -int -main(int argc, char *argv[]) -{ - struct unixctl_server *unixctl; - struct ovn_exit_args exit_args = {0}; - struct br_int_remote br_int_remote = {0}; - int retval; + /* Keep en_addr_sets before en_runtime_data because + * lflow_output_runtime_data_handler may *partially* reprocess a lflow when + * the lflow is attached to a DP group and a new DP in that DP group is + * added locally, i.e. reprocessing the lflow for the new DP only but not + * for the other DPs in the group. If we handle en_addr_sets after this, + * incrementally processing an updated address set for the added IPs may + * end up adding redundant flows/conjunctions for the lflow agaist the new + * DP because it has been processed on the DP already. */ + engine_add_input(&en_lflow_output, &en_addr_sets, + lflow_output_addr_sets_handler); + engine_add_input(&en_lflow_output, &en_port_groups, + lflow_output_port_groups_handler); + engine_add_input(&en_lflow_output, &en_template_vars, + lflow_output_template_vars_handler); + engine_add_input(&en_lflow_output, &en_runtime_data, + lflow_output_runtime_data_handler); + engine_add_input(&en_lflow_output, &en_non_vif_data, + NULL); - /* Read from system-id-override file once on startup. */ - file_system_id = get_file_system_id(); + engine_add_input(&en_lflow_output, &en_sb_multicast_group, + lflow_output_sb_multicast_group_handler); - ovs_cmdl_proctitle_init(argc, argv); - ovn_set_program_name(argv[0]); - service_start(&argc, &argv); - char *ovs_remote = parse_options(argc, argv); - fatal_ignore_sigpipe(); + engine_add_input(&en_lflow_output, &en_sb_chassis, + pflow_lflow_output_sb_chassis_handler); - daemonize_start(true, false); + engine_add_input(&en_lflow_output, &en_sb_port_binding, + lflow_output_sb_port_binding_handler); - char *abs_unixctl_path = get_abs_unix_ctl_path(unixctl_path); - retval = unixctl_server_create(abs_unixctl_path, &unixctl); - free(abs_unixctl_path); - if (retval) { - exit(EXIT_FAILURE); - } - unixctl_command_register("exit", "", 0, 1, ovn_exit_command_callback, - &exit_args); + engine_add_input(&en_lflow_output, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_lflow_output, &en_ovs_bridge, NULL); + engine_add_input(&en_lflow_output, &en_ovs_flow_sample_collector_set, + lflow_output_flow_sample_collector_set_handler); - daemonize_complete(); + engine_add_input(&en_lflow_output, &en_sb_mac_binding, + lflow_output_sb_mac_binding_handler); + engine_add_input(&en_lflow_output, &en_sb_static_mac_binding, + lflow_output_sb_static_mac_binding_handler); + engine_add_input(&en_lflow_output, &en_sb_logical_flow, + lflow_output_sb_logical_flow_handler); + /* Using a noop handler since we don't really need any data from datapath + * groups or a full recompute. Update of a datapath group will put + * logical flow into the tracked list, so the logical flow handler will + * process all changes. */ + engine_add_input(&en_lflow_output, &en_sb_logical_dp_group, + engine_noop_handler); - /* Register ofctrl seqno types. */ - ofctrl_seq_type_nb_cfg = ofctrl_seqno_add_type(); + engine_add_input(&en_lflow_output, &en_lb_data, + lflow_output_lb_data_handler); + engine_add_input(&en_lflow_output, &en_sb_fdb, + lflow_output_sb_fdb_handler); + engine_add_input(&en_lflow_output, &en_sb_meter, + lflow_output_sb_meter_handler); - patch_init(); - pinctrl_init(); - lflow_init(); - mirror_init(); - vif_plug_provider_initialize(); - statctrl_init(); - dns_resolve_init(true); + engine_add_input(&en_ct_zones, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_ct_zones, &en_ovs_bridge, NULL); + engine_add_input(&en_ct_zones, &en_sb_datapath_binding, + ct_zones_datapath_binding_handler); + engine_add_input(&en_ct_zones, &en_runtime_data, + ct_zones_runtime_data_handler); - /* Connect to OVS OVSDB instance. */ - struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( - ovsdb_idl_create(ovs_remote, &ovsrec_idl_class, false, true)); - ctrl_register_ovs_idl(ovs_idl_loop.idl); + engine_add_input(&en_ovs_interface_shadow, &en_ovs_interface, + ovs_interface_shadow_ovs_interface_handler); - struct ovsdb_idl_index *ovsrec_port_by_interfaces - = ovsdb_idl_index_create1(ovs_idl_loop.idl, - &ovsrec_port_col_interfaces); - struct ovsdb_idl_index *ovsrec_port_by_name - = ovsdb_idl_index_create1(ovs_idl_loop.idl, - &ovsrec_port_col_name); - struct ovsdb_idl_index *ovsrec_port_by_qos - = ovsdb_idl_index_create1(ovs_idl_loop.idl, - &ovsrec_port_col_qos); - struct ovsdb_idl_index *ovsrec_interface_by_name - = ovsdb_idl_index_create1(ovs_idl_loop.idl, - &ovsrec_interface_col_name); - struct ovsdb_idl_index *ovsrec_queue_by_external_ids - = ovsdb_idl_index_create1(ovs_idl_loop.idl, - &ovsrec_queue_col_external_ids); - struct ovsdb_idl_index *ovsrec_flow_sample_collector_set_by_id - = ovsdb_idl_index_create2(ovs_idl_loop.idl, - &ovsrec_flow_sample_collector_set_col_bridge, - &ovsrec_flow_sample_collector_set_col_id); + engine_add_input(&en_runtime_data, &en_ofctrl_is_connected, NULL); - ovsdb_idl_get_initial_snapshot(ovs_idl_loop.idl); + engine_add_input(&en_runtime_data, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_runtime_data, &en_ovs_bridge, NULL); + engine_add_input(&en_runtime_data, &en_ovs_qos, NULL); + engine_add_input(&en_runtime_data, &en_ovs_queue, NULL); - /* Configure OVN SB database. */ - struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( - ovsdb_idl_create_unconnected(&sbrec_idl_class, true)); - ovsdb_idl_set_leader_only(ovnsb_idl_loop.idl, false); + engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); + engine_add_input(&en_runtime_data, &en_sb_datapath_binding, + runtime_data_sb_datapath_binding_handler); + engine_add_input(&en_runtime_data, &en_sb_port_binding, + runtime_data_sb_port_binding_handler); + /* Reuse the same handler for any previously postponed ports. */ + engine_add_input(&en_runtime_data, &en_postponed_ports, + runtime_data_sb_port_binding_handler); + /* Run sb_ro_handler after port_binding_handler in case port get deleted */ + engine_add_input(&en_runtime_data, &en_sb_ro, runtime_data_sb_ro_handler); - unixctl_command_register("connection-status", "", 0, 0, - ovn_conn_show, ovnsb_idl_loop.idl); + /* The OVS interface handler for runtime_data changes MUST be executed + * after the sb_port_binding_handler as port_binding deletes must be + * processed first. + * + * runtime_data needs to access the OVS Port data and hence a noop + * handler. + */ + engine_add_input(&en_runtime_data, &en_ovs_port, + engine_noop_handler); + engine_add_input(&en_runtime_data, &en_ovs_interface_shadow, + runtime_data_ovs_interface_shadow_handler); - struct ovsdb_idl_index *sbrec_chassis_by_name - = chassis_index_create(ovnsb_idl_loop.idl); - struct ovsdb_idl_index *sbrec_chassis_private_by_name - = chassis_private_index_create(ovnsb_idl_loop.idl); + engine_add_input(&en_mac_cache, &en_runtime_data, + mac_cache_runtime_data_handler); + engine_add_input(&en_mac_cache, &en_sb_mac_binding, + mac_cache_sb_mac_binding_handler); + engine_add_input(&en_mac_cache, &en_sb_fdb, + mac_cache_sb_fdb_handler); + engine_add_input(&en_mac_cache, &en_sb_datapath_binding, + mac_cache_sb_datapath_binding_handler); + engine_add_input(&en_mac_cache, &en_sb_port_binding, + engine_noop_handler); + + engine_add_input(&en_dns_cache, &en_sb_dns, + dns_cache_sb_dns_handler); + + engine_add_input(&en_garp_rarp, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_garp_rarp, &en_sb_chassis, NULL); + engine_add_input(&en_garp_rarp, &en_sb_port_binding, + garp_rarp_sb_port_binding_handler); + engine_add_input(&en_garp_rarp, &en_sb_datapath_binding, + garp_rarp_sb_datapath_binding_handler); + /* The mac_binding data is just used in an index to filter duplicates when + * inserting data to the southbound. */ + engine_add_input(&en_garp_rarp, &en_sb_mac_binding, engine_noop_handler); + engine_add_input(&en_garp_rarp, &en_runtime_data, + garp_rarp_runtime_data_handler); + + engine_add_input(&en_neighbor, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_neighbor, &en_sb_chassis, NULL); + engine_add_input(&en_neighbor, &en_sb_advertised_mac_binding, NULL); + engine_add_input(&en_neighbor, &en_runtime_data, + neighbor_runtime_data_handler); + engine_add_input(&en_neighbor, &en_sb_datapath_binding, + neighbor_sb_datapath_binding_handler); + engine_add_input(&en_neighbor, &en_sb_port_binding, + neighbor_sb_port_binding_handler); + engine_add_input(&en_neighbor_exchange, &en_neighbor, NULL); + engine_add_input(&en_neighbor_exchange, &en_host_if_monitor, NULL); + engine_add_input(&en_neighbor_exchange, &en_neighbor_table_notify, NULL); + engine_add_input(&en_neighbor_exchange, &en_neighbor_exchange_status, + NULL); + + engine_add_input(&en_evpn_vtep_binding, &en_ovs_open_vswitch, NULL); + engine_add_input(&en_evpn_vtep_binding, &en_ovs_bridge, NULL); + engine_add_input(&en_evpn_vtep_binding, &en_neighbor_exchange, NULL); + /* The runtime_data are needed only for local datapaths, any update of + * local datapath will be reflected via en_neighbor_exchange. */ + engine_add_input(&en_evpn_vtep_binding, &en_runtime_data, + engine_noop_handler); + engine_add_input(&en_evpn_vtep_binding, &en_ovs_interface, + evpn_vtep_binding_ovs_interface_handler); + engine_add_input(&en_evpn_vtep_binding, &en_sb_datapath_binding, + evpn_vtep_binding_datapath_binding_handler); + + engine_add_input(&en_evpn_fdb, &en_neighbor_exchange, NULL); + engine_add_input(&en_evpn_fdb, &en_evpn_vtep_binding, + evpn_fdb_vtep_binding_handler); + + engine_add_input(&en_evpn_arp, &en_neighbor_exchange, NULL); + engine_add_input(&en_evpn_arp, &en_evpn_vtep_binding, + evpn_arp_vtep_binding_handler); + + engine_add_input(&en_pflow_output, &en_evpn_vtep_binding, + pflow_output_evpn_binding_handler); + engine_add_input(&en_pflow_output, &en_evpn_fdb, + pflow_output_fdb_handler); + engine_add_input(&en_pflow_output, &en_evpn_arp, + pflow_output_arp_handler); + + engine_add_input(&en_controller_output, &en_dns_cache, + NULL); + engine_add_input(&en_controller_output, &en_lflow_output, + controller_output_lflow_output_handler); + engine_add_input(&en_controller_output, &en_pflow_output, + controller_output_pflow_output_handler); + engine_add_input(&en_controller_output, &en_mac_cache, + controller_output_mac_cache_handler); + engine_add_input(&en_controller_output, &en_bfd_chassis, + controller_output_bfd_chassis_handler); + engine_add_input(&en_controller_output, &en_route_exchange, + controller_output_route_exchange_handler); + engine_add_input(&en_controller_output, &en_garp_rarp, + controller_output_garp_rarp_handler); + + engine_add_input(&en_acl_id, &en_sb_acl_id, NULL); + engine_add_input(&en_controller_output, &en_acl_id, + controller_output_acl_id_handler); + + struct engine_arg engine_arg = { + .sb_idl = sb_idl_loop->idl, + .ovs_idl = ovs_idl_loop->idl, + }; + engine_init(&en_controller_output, &engine_arg); + + engine_ovsdb_node_add_index(&en_sb_chassis, "name", sbrec_chassis_by_name); struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath - = mcast_group_index_create(ovnsb_idl_loop.idl); - struct ovsdb_idl_index *sbrec_meter_by_name - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, &sbrec_meter_col_name); + = mcast_group_index_create(sb_idl_loop->idl); + engine_ovsdb_node_add_index(&en_sb_multicast_group, "name_datapath", + sbrec_multicast_group_by_name_datapath); + struct ovsdb_idl_index *sbrec_logical_flow_by_logical_datapath - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_logical_flow_col_logical_datapath); + engine_ovsdb_node_add_index(&en_sb_logical_flow, "logical_datapath", + sbrec_logical_flow_by_logical_datapath); + struct ovsdb_idl_index *sbrec_logical_flow_by_logical_dp_group - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_logical_flow_col_logical_dp_group); - struct ovsdb_idl_index *sbrec_port_binding_by_name - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, - &sbrec_port_binding_col_logical_port); - struct ovsdb_idl_index *sbrec_port_binding_by_key - = ovsdb_idl_index_create2(ovnsb_idl_loop.idl, - &sbrec_port_binding_col_tunnel_key, - &sbrec_port_binding_col_datapath); + engine_ovsdb_node_add_index(&en_sb_logical_flow, "logical_dp_group", + sbrec_logical_flow_by_logical_dp_group); + + engine_ovsdb_node_add_index(&en_sb_port_binding, "name", + sbrec_port_binding_by_name); + + engine_ovsdb_node_add_index(&en_sb_port_binding, "key", + sbrec_port_binding_by_key); + struct ovsdb_idl_index *sbrec_port_binding_by_datapath - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_port_binding_col_datapath); - struct ovsdb_idl_index *sbrec_port_binding_by_type - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, - &sbrec_port_binding_col_type); - struct ovsdb_idl_index *sbrec_port_binding_by_requested_chassis - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, - &sbrec_port_binding_col_requested_chassis); - struct ovsdb_idl_index *sbrec_datapath_binding_by_key - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, - &sbrec_datapath_binding_col_tunnel_key); - struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip - = mac_binding_by_lport_ip_index_create(ovnsb_idl_loop.idl); - struct ovsdb_idl_index *sbrec_ip_multicast - = ip_mcast_index_create(ovnsb_idl_loop.idl); - struct ovsdb_idl_index *sbrec_igmp_group - = igmp_group_index_create(ovnsb_idl_loop.idl); + engine_ovsdb_node_add_index(&en_sb_port_binding, "datapath", + sbrec_port_binding_by_datapath); + + engine_ovsdb_node_add_index(&en_sb_datapath_binding, "key", + sbrec_datapath_binding_by_key); + struct ovsdb_idl_index *sbrec_fdb_by_dp_key - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, - &sbrec_fdb_col_dp_key); - struct ovsdb_idl_index *sbrec_fdb_by_dp_key_mac - = ovsdb_idl_index_create2(ovnsb_idl_loop.idl, - &sbrec_fdb_col_mac, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_fdb_col_dp_key); + engine_ovsdb_node_add_index(&en_sb_fdb, "dp_key", + sbrec_fdb_by_dp_key); + struct ovsdb_idl_index *sbrec_mac_binding_by_datapath - = mac_binding_by_datapath_index_create(ovnsb_idl_loop.idl); + = mac_binding_by_datapath_index_create(sb_idl_loop->idl); + engine_ovsdb_node_add_index(&en_sb_mac_binding, "datapath", + sbrec_mac_binding_by_datapath); + struct ovsdb_idl_index *sbrec_static_mac_binding_by_datapath - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_static_mac_binding_col_datapath); + engine_ovsdb_node_add_index(&en_sb_static_mac_binding, "datapath", + sbrec_static_mac_binding_by_datapath); + struct ovsdb_idl_index *sbrec_chassis_template_var_index_by_chassis - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_chassis_template_var_col_chassis); + engine_ovsdb_node_add_index(&en_sb_chassis_template_var, "chassis", + sbrec_chassis_template_var_index_by_chassis); + struct ovsdb_idl_index *sbrec_learned_route_index_by_datapath - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_learned_route_col_datapath); + engine_ovsdb_node_add_index(&en_sb_learned_route, "datapath", + sbrec_learned_route_index_by_datapath); + struct ovsdb_idl_index *sbrec_advertised_mac_binding_index_by_dp - = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + = ovsdb_idl_index_create1(sb_idl_loop->idl, &sbrec_advertised_mac_binding_col_datapath); - struct ovsdb_idl_index *sbrec_encaps_index_by_ip_and_type - = ovsdb_idl_index_create2(ovnsb_idl_loop.idl, - &sbrec_encap_col_type, &sbrec_encap_col_ip); + engine_ovsdb_node_add_index(&en_sb_advertised_mac_binding, "datapath", + sbrec_advertised_mac_binding_index_by_dp); - ovsdb_idl_track_add_all(ovnsb_idl_loop.idl); - ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, - &sbrec_chassis_private_col_nb_cfg); - ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, - &sbrec_chassis_private_col_nb_cfg_timestamp); - /* Omit the timestamp columns of the MAC_Binding and FDB tables. - * ovn-controller doesn't need to react to changes in timestamp - * values (it does read them to implement aging). Therefore we - * can disable change tracking and alerting for these columns. */ - ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_timestamp); - ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_fdb_col_timestamp); + engine_ovsdb_node_add_index(&en_sb_mac_binding, "lport_ip", + sbrec_mac_binding_by_lport_ip); - /* Omit the external_ids column of all the tables except for - - * - DNS. pinctrl.c uses the external_ids column of DNS, - * which it shouldn't. This should be removed. - * - * - Datapath_binding - lflow.c is using this to check if the datapath - * is switch or not. This should be removed. - * */ + engine_ovsdb_node_add_index(&en_ovs_flow_sample_collector_set, "id", + ovsrec_flow_sample_collector_set_by_id); + engine_ovsdb_node_add_index(&en_ovs_port, "qos", ovsrec_port_by_qos); + engine_ovsdb_node_add_index(&en_ovs_interface, "name", + ovsrec_interface_by_name); + engine_ovsdb_node_add_index(&en_ovs_queue, "external_ids", + ovsrec_queue_by_external_ids); +} - ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_sb_global_col_external_ids); - ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_external_ids); - ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_port_binding_col_external_ids); - ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_ssl_col_external_ids); - ovsdb_idl_omit(ovnsb_idl_loop.idl, - &sbrec_gateway_chassis_col_external_ids); +/* Returns false if the northd internal version stored in SB_Global + * and ovn-controller internal version don't match. + */ +static bool +check_northd_version(struct ovsdb_idl *ovs_idl, struct ovsdb_idl *ovnsb_idl, + const char *version) +{ + static bool version_mismatch; + + const struct ovsrec_open_vswitch *cfg = ovsrec_open_vswitch_first(ovs_idl); + const struct ovsrec_open_vswitch_table *ovs_table = + ovsrec_open_vswitch_table_get(ovs_idl); + const char *chassis_id = get_ovs_chassis_id(ovs_table); + if (!cfg || !get_chassis_external_id_value_bool( + &cfg->external_ids, chassis_id, + "ovn-match-northd-version", false)) { + version_mismatch = false; + return true; + } + + const struct sbrec_sb_global *sb = sbrec_sb_global_first(ovnsb_idl); + if (!sb) { + version_mismatch = true; + return false; + } + + const char *northd_version = + smap_get_def(&sb->options, "northd_internal_version", ""); + + if (strcmp(northd_version, version)) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_WARN_RL(&rl, "controller version - %s mismatch with northd " + "version - %s", version, northd_version); + version_mismatch = true; + return false; + } + + /* If there used to be a mismatch and ovn-northd got updated, force a + * full recompute. + */ + if (version_mismatch) { + engine_set_force_recompute(); + } + version_mismatch = false; + return true; +} + +static void +br_int_remote_update(struct br_int_remote *remote, + const struct ovsrec_bridge *br_int, + const struct ovsrec_open_vswitch_table *ovs_table) +{ + if (!br_int) { + return; + } + + const struct ovsrec_open_vswitch *cfg = + ovsrec_open_vswitch_table_first(ovs_table); + + const char *ext_target = + smap_get(&cfg->external_ids, "ovn-bridge-remote"); + char *target = ext_target + ? xstrdup(ext_target) + : xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name); + + if (!remote->target || strcmp(remote->target, target)) { + free(remote->target); + remote->target = target; + } else { + free(target); + } + + unsigned long long probe_interval = + smap_get_ullong(&cfg->external_ids, + "ovn-bridge-remote-probe-interval", 0); + remote->probe_interval = MIN(probe_interval / 1000, INT_MAX); +} + +static void +ovsdb_idl_loop_next_cfg_inc(struct ovsdb_idl_loop *idl_loop) +{ + if (idl_loop->next_cfg == INT64_MAX) { + idl_loop->next_cfg = 0; + } else { + idl_loop->next_cfg++; + } +} + +int +main(int argc, char *argv[]) +{ + struct unixctl_server *unixctl; + struct ovn_exit_args exit_args = {0}; + struct br_int_remote br_int_remote = {0}; + int retval; + + /* Read from system-id-override file once on startup. */ + file_system_id = get_file_system_id(); + + ovs_cmdl_proctitle_init(argc, argv); + ovn_set_program_name(argv[0]); + service_start(&argc, &argv); + char *ovs_remote = parse_options(argc, argv); + fatal_ignore_sigpipe(); + + daemonize_start(true, false); + + char *abs_unixctl_path = get_abs_unix_ctl_path(unixctl_path); + retval = unixctl_server_create(abs_unixctl_path, &unixctl); + free(abs_unixctl_path); + if (retval) { + exit(EXIT_FAILURE); + } + unixctl_command_register("exit", "", 0, 1, ovn_exit_command_callback, + &exit_args); + + daemonize_complete(); + + /* Register ofctrl seqno types. */ + ofctrl_seq_type_nb_cfg = ofctrl_seqno_add_type(); + + patch_init(); + pinctrl_init(); + lflow_init(); + mirror_init(); + vif_plug_provider_initialize(); + statctrl_init(); + dns_resolve_init(true); + + /* Connect to OVS OVSDB instance. */ + struct ovsdb_idl_loop ovs_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( + ovsdb_idl_create(ovs_remote, &ovsrec_idl_class, false, true)); + ctrl_register_ovs_idl(ovs_idl_loop.idl); + + struct ovsdb_idl_index *ovsrec_port_by_interfaces + = ovsdb_idl_index_create1(ovs_idl_loop.idl, + &ovsrec_port_col_interfaces); + struct ovsdb_idl_index *ovsrec_port_by_name + = ovsdb_idl_index_create1(ovs_idl_loop.idl, + &ovsrec_port_col_name); + struct ovsdb_idl_index *ovsrec_port_by_qos + = ovsdb_idl_index_create1(ovs_idl_loop.idl, + &ovsrec_port_col_qos); + struct ovsdb_idl_index *ovsrec_interface_by_name + = ovsdb_idl_index_create1(ovs_idl_loop.idl, + &ovsrec_interface_col_name); + struct ovsdb_idl_index *ovsrec_flow_sample_collector_set_by_id + = ovsdb_idl_index_create2(ovs_idl_loop.idl, + &ovsrec_flow_sample_collector_set_col_bridge, + &ovsrec_flow_sample_collector_set_col_id); + struct ovsdb_idl_index *ovsrec_queue_by_external_ids + = ovsdb_idl_index_create1(ovs_idl_loop.idl, + &ovsrec_queue_col_external_ids); + + ovsdb_idl_get_initial_snapshot(ovs_idl_loop.idl); + + /* Configure OVN SB database. */ + struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( + ovsdb_idl_create_unconnected(&sbrec_idl_class, true)); + ovsdb_idl_set_leader_only(ovnsb_idl_loop.idl, false); + + unixctl_command_register("connection-status", "", 0, 0, + ovn_conn_show, ovnsb_idl_loop.idl); + + struct ovsdb_idl_index *sbrec_chassis_by_name + = chassis_index_create(ovnsb_idl_loop.idl); + struct ovsdb_idl_index *sbrec_chassis_private_by_name + = chassis_private_index_create(ovnsb_idl_loop.idl); + struct ovsdb_idl_index *sbrec_meter_by_name + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, &sbrec_meter_col_name); + struct ovsdb_idl_index *sbrec_port_binding_by_name + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + &sbrec_port_binding_col_logical_port); + struct ovsdb_idl_index *sbrec_port_binding_by_key + = ovsdb_idl_index_create2(ovnsb_idl_loop.idl, + &sbrec_port_binding_col_tunnel_key, + &sbrec_port_binding_col_datapath); + struct ovsdb_idl_index *sbrec_port_binding_by_type + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + &sbrec_port_binding_col_type); + struct ovsdb_idl_index *sbrec_port_binding_by_requested_chassis + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + &sbrec_port_binding_col_requested_chassis); + struct ovsdb_idl_index *sbrec_datapath_binding_by_key + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + &sbrec_datapath_binding_col_tunnel_key); + struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip + = mac_binding_by_lport_ip_index_create(ovnsb_idl_loop.idl); + struct ovsdb_idl_index *sbrec_ip_multicast + = ip_mcast_index_create(ovnsb_idl_loop.idl); + struct ovsdb_idl_index *sbrec_igmp_group + = igmp_group_index_create(ovnsb_idl_loop.idl); + struct ovsdb_idl_index *sbrec_fdb_by_dp_key_mac + = ovsdb_idl_index_create2(ovnsb_idl_loop.idl, + &sbrec_fdb_col_mac, + &sbrec_fdb_col_dp_key); + struct ovsdb_idl_index *sbrec_encaps_index_by_ip_and_type + = ovsdb_idl_index_create2(ovnsb_idl_loop.idl, + &sbrec_encap_col_type, &sbrec_encap_col_ip); + + ovsdb_idl_track_add_all(ovnsb_idl_loop.idl); + ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, + &sbrec_chassis_private_col_nb_cfg); + ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, + &sbrec_chassis_private_col_nb_cfg_timestamp); + /* Omit the timestamp columns of the MAC_Binding and FDB tables. + * ovn-controller doesn't need to react to changes in timestamp + * values (it does read them to implement aging). Therefore we + * can disable change tracking and alerting for these columns. */ + ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_mac_binding_col_timestamp); + ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_fdb_col_timestamp); + + /* Omit the external_ids column of all the tables except for - + * - DNS. pinctrl.c uses the external_ids column of DNS, + * which it shouldn't. This should be removed. + * + * - Datapath_binding - lflow.c is using this to check if the datapath + * is switch or not. This should be removed. + * */ + + ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_sb_global_col_external_ids); + ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_logical_flow_col_external_ids); + ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_port_binding_col_external_ids); + ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_ssl_col_external_ids); + ovsdb_idl_omit(ovnsb_idl_loop.idl, + &sbrec_gateway_chassis_col_external_ids); ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_ha_chassis_col_external_ids); ovsdb_idl_omit(ovnsb_idl_loop.idl, &sbrec_ha_chassis_group_col_external_ids); @@ -6879,327 +7231,16 @@ main(int argc, char *argv[]) stopwatch_create(BFD_RUN_STOPWATCH_NAME, SW_MS); stopwatch_create(VIF_PLUG_RUN_STOPWATCH_NAME, SW_MS); - /* Add dependencies between inc-proc-engine nodes. */ - engine_add_input(&en_template_vars, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_template_vars, &en_sb_chassis, NULL); - engine_add_input(&en_template_vars, &en_sb_chassis_template_var, - template_vars_sb_chassis_template_var_handler); - - engine_add_input(&en_lb_data, &en_sb_load_balancer, - lb_data_sb_load_balancer_handler); - engine_add_input(&en_lb_data, &en_template_vars, - lb_data_template_var_handler); - engine_add_input(&en_lb_data, &en_runtime_data, - lb_data_runtime_data_handler); - - engine_add_input(&en_route, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_route, &en_sb_chassis, NULL); - engine_add_input(&en_route, &en_sb_port_binding, - route_sb_port_binding_data_handler); - engine_add_input(&en_route, &en_runtime_data, - route_runtime_data_handler); - engine_add_input(&en_route, &en_sb_advertised_route, - route_sb_advertised_route_data_handler); - - engine_add_input(&en_route_exchange, &en_route, NULL); - engine_add_input(&en_route_exchange, &en_sb_learned_route, - engine_noop_handler); - engine_add_input(&en_route_exchange, &en_sb_port_binding, - engine_noop_handler); - engine_add_input(&en_route_exchange, &en_route_table_notify, NULL); - engine_add_input(&en_route_exchange, &en_route_exchange_status, NULL); - engine_add_input(&en_route_exchange, &en_sb_ro, - route_exchange_sb_ro_handler); - - engine_add_input(&en_addr_sets, &en_sb_address_set, - addr_sets_sb_address_set_handler); - engine_add_input(&en_port_groups, &en_sb_port_group, - port_groups_sb_port_group_handler); - /* port_groups computation requires runtime_data's lbinding_data for the - * locally bound ports. */ - engine_add_input(&en_port_groups, &en_runtime_data, - port_groups_runtime_data_handler); - - engine_add_input(&en_non_vif_data, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_non_vif_data, &en_ovs_bridge, NULL); - engine_add_input(&en_non_vif_data, &en_sb_chassis, NULL); - engine_add_input(&en_non_vif_data, &en_ovs_interface, - non_vif_data_ovs_iface_handler); - - engine_add_input(&en_if_status_mgr, &en_ovs_interface, - if_status_mgr_ovs_interface_handler); - engine_add_input(&en_bfd_chassis, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_bfd_chassis, &en_sb_chassis, NULL); - engine_add_input(&en_bfd_chassis, &en_sb_ha_chassis_group, NULL); - - /* Note: The order of inputs is important, all OVS interface changes must - * be handled before any ct_zone changes. - */ - engine_add_input(&en_pflow_output, &en_non_vif_data, - NULL); - engine_add_input(&en_pflow_output, &en_northd_options, NULL); - engine_add_input(&en_pflow_output, &en_ct_zones, - pflow_output_ct_zones_handler); - engine_add_input(&en_pflow_output, &en_sb_chassis, - pflow_lflow_output_sb_chassis_handler); - - engine_add_input(&en_pflow_output, &en_if_status_mgr, - pflow_output_if_status_mgr_handler); - engine_add_input(&en_pflow_output, &en_sb_port_binding, - pflow_output_sb_port_binding_handler); - engine_add_input(&en_pflow_output, &en_sb_multicast_group, - pflow_output_sb_multicast_group_handler); - - /* pflow_output needs to access the SB datapath binding and hence a noop - * handler. - */ - engine_add_input(&en_pflow_output, &en_sb_datapath_binding, - engine_noop_handler); - engine_add_input(&en_pflow_output, &en_activated_ports, - pflow_output_activated_ports_handler); - - engine_add_input(&en_pflow_output, &en_runtime_data, - pflow_output_runtime_data_handler); - engine_add_input(&en_pflow_output, &en_sb_encap, NULL); - engine_add_input(&en_pflow_output, &en_mff_ovn_geneve, NULL); - engine_add_input(&en_pflow_output, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_pflow_output, &en_ovs_bridge, NULL); - engine_add_input(&en_pflow_output, &en_ovs_flow_sample_collector_set, - pflow_output_debug_handler); - engine_add_input(&en_pflow_output, &en_sb_sb_global, - pflow_output_debug_handler); - - engine_add_input(&en_northd_options, &en_sb_sb_global, - en_northd_options_sb_sb_global_handler); - - engine_add_input(&en_dhcp_options, &en_sb_dhcp_options, NULL); - engine_add_input(&en_dhcp_options, &en_sb_dhcpv6_options, NULL); - - engine_add_input(&en_lflow_output, &en_northd_options, NULL); - engine_add_input(&en_lflow_output, &en_dhcp_options, NULL); - - /* Keep en_addr_sets before en_runtime_data because - * lflow_output_runtime_data_handler may *partially* reprocess a lflow when - * the lflow is attached to a DP group and a new DP in that DP group is - * added locally, i.e. reprocessing the lflow for the new DP only but not - * for the other DPs in the group. If we handle en_addr_sets after this, - * incrementally processing an updated address set for the added IPs may - * end up adding redundant flows/conjunctions for the lflow agaist the new - * DP because it has been processed on the DP already. */ - engine_add_input(&en_lflow_output, &en_addr_sets, - lflow_output_addr_sets_handler); - engine_add_input(&en_lflow_output, &en_port_groups, - lflow_output_port_groups_handler); - engine_add_input(&en_lflow_output, &en_template_vars, - lflow_output_template_vars_handler); - engine_add_input(&en_lflow_output, &en_runtime_data, - lflow_output_runtime_data_handler); - engine_add_input(&en_lflow_output, &en_non_vif_data, - NULL); - - engine_add_input(&en_lflow_output, &en_sb_multicast_group, - lflow_output_sb_multicast_group_handler); - - engine_add_input(&en_lflow_output, &en_sb_chassis, - pflow_lflow_output_sb_chassis_handler); - - engine_add_input(&en_lflow_output, &en_sb_port_binding, - lflow_output_sb_port_binding_handler); - - engine_add_input(&en_lflow_output, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_lflow_output, &en_ovs_bridge, NULL); - engine_add_input(&en_lflow_output, &en_ovs_flow_sample_collector_set, - lflow_output_flow_sample_collector_set_handler); - - engine_add_input(&en_lflow_output, &en_sb_mac_binding, - lflow_output_sb_mac_binding_handler); - engine_add_input(&en_lflow_output, &en_sb_static_mac_binding, - lflow_output_sb_static_mac_binding_handler); - engine_add_input(&en_lflow_output, &en_sb_logical_flow, - lflow_output_sb_logical_flow_handler); - /* Using a noop handler since we don't really need any data from datapath - * groups or a full recompute. Update of a datapath group will put - * logical flow into the tracked list, so the logical flow handler will - * process all changes. */ - engine_add_input(&en_lflow_output, &en_sb_logical_dp_group, - engine_noop_handler); - - engine_add_input(&en_lflow_output, &en_lb_data, - lflow_output_lb_data_handler); - engine_add_input(&en_lflow_output, &en_sb_fdb, - lflow_output_sb_fdb_handler); - engine_add_input(&en_lflow_output, &en_sb_meter, - lflow_output_sb_meter_handler); - - engine_add_input(&en_ct_zones, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_ct_zones, &en_ovs_bridge, NULL); - engine_add_input(&en_ct_zones, &en_sb_datapath_binding, - ct_zones_datapath_binding_handler); - engine_add_input(&en_ct_zones, &en_runtime_data, - ct_zones_runtime_data_handler); - - engine_add_input(&en_ovs_interface_shadow, &en_ovs_interface, - ovs_interface_shadow_ovs_interface_handler); - - engine_add_input(&en_runtime_data, &en_ofctrl_is_connected, NULL); - - engine_add_input(&en_runtime_data, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_runtime_data, &en_ovs_bridge, NULL); - engine_add_input(&en_runtime_data, &en_ovs_qos, NULL); - engine_add_input(&en_runtime_data, &en_ovs_queue, NULL); - - engine_add_input(&en_runtime_data, &en_sb_chassis, NULL); - engine_add_input(&en_runtime_data, &en_sb_datapath_binding, - runtime_data_sb_datapath_binding_handler); - engine_add_input(&en_runtime_data, &en_sb_port_binding, - runtime_data_sb_port_binding_handler); - /* Reuse the same handler for any previously postponed ports. */ - engine_add_input(&en_runtime_data, &en_postponed_ports, - runtime_data_sb_port_binding_handler); - /* Run sb_ro_handler after port_binding_handler in case port get deleted */ - engine_add_input(&en_runtime_data, &en_sb_ro, runtime_data_sb_ro_handler); - - /* The OVS interface handler for runtime_data changes MUST be executed - * after the sb_port_binding_handler as port_binding deletes must be - * processed first. - * - * runtime_data needs to access the OVS Port data and hence a noop - * handler. - */ - engine_add_input(&en_runtime_data, &en_ovs_port, - engine_noop_handler); - engine_add_input(&en_runtime_data, &en_ovs_interface_shadow, - runtime_data_ovs_interface_shadow_handler); - - engine_add_input(&en_mac_cache, &en_runtime_data, - mac_cache_runtime_data_handler); - engine_add_input(&en_mac_cache, &en_sb_mac_binding, - mac_cache_sb_mac_binding_handler); - engine_add_input(&en_mac_cache, &en_sb_fdb, - mac_cache_sb_fdb_handler); - engine_add_input(&en_mac_cache, &en_sb_datapath_binding, - mac_cache_sb_datapath_binding_handler); - engine_add_input(&en_mac_cache, &en_sb_port_binding, - engine_noop_handler); - - engine_add_input(&en_dns_cache, &en_sb_dns, - dns_cache_sb_dns_handler); - - engine_add_input(&en_garp_rarp, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_garp_rarp, &en_sb_chassis, NULL); - engine_add_input(&en_garp_rarp, &en_sb_port_binding, - garp_rarp_sb_port_binding_handler); - engine_add_input(&en_garp_rarp, &en_sb_datapath_binding, - garp_rarp_sb_datapath_binding_handler); - /* The mac_binding data is just used in an index to filter duplicates when - * inserting data to the southbound. */ - engine_add_input(&en_garp_rarp, &en_sb_mac_binding, engine_noop_handler); - engine_add_input(&en_garp_rarp, &en_runtime_data, - garp_rarp_runtime_data_handler); - - engine_add_input(&en_neighbor, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_neighbor, &en_sb_chassis, NULL); - engine_add_input(&en_neighbor, &en_sb_advertised_mac_binding, NULL); - engine_add_input(&en_neighbor, &en_runtime_data, - neighbor_runtime_data_handler); - engine_add_input(&en_neighbor, &en_sb_datapath_binding, - neighbor_sb_datapath_binding_handler); - engine_add_input(&en_neighbor, &en_sb_port_binding, - neighbor_sb_port_binding_handler); - engine_add_input(&en_neighbor_exchange, &en_neighbor, NULL); - engine_add_input(&en_neighbor_exchange, &en_host_if_monitor, NULL); - engine_add_input(&en_neighbor_exchange, &en_neighbor_table_notify, NULL); - engine_add_input(&en_neighbor_exchange, &en_neighbor_exchange_status, - NULL); - - engine_add_input(&en_evpn_vtep_binding, &en_ovs_open_vswitch, NULL); - engine_add_input(&en_evpn_vtep_binding, &en_ovs_bridge, NULL); - engine_add_input(&en_evpn_vtep_binding, &en_neighbor_exchange, NULL); - /* The runtime_data are needed only for local datapaths, any update of - * local datapath will be reflected via en_neighbor_exchange. */ - engine_add_input(&en_evpn_vtep_binding, &en_runtime_data, - engine_noop_handler); - engine_add_input(&en_evpn_vtep_binding, &en_ovs_interface, - evpn_vtep_binding_ovs_interface_handler); - engine_add_input(&en_evpn_vtep_binding, &en_sb_datapath_binding, - evpn_vtep_binding_datapath_binding_handler); - - engine_add_input(&en_evpn_fdb, &en_neighbor_exchange, NULL); - engine_add_input(&en_evpn_fdb, &en_evpn_vtep_binding, - evpn_fdb_vtep_binding_handler); - - engine_add_input(&en_evpn_arp, &en_neighbor_exchange, NULL); - engine_add_input(&en_evpn_arp, &en_evpn_vtep_binding, - evpn_arp_vtep_binding_handler); - - engine_add_input(&en_pflow_output, &en_evpn_vtep_binding, - pflow_output_evpn_binding_handler); - engine_add_input(&en_pflow_output, &en_evpn_fdb, - pflow_output_fdb_handler); - engine_add_input(&en_pflow_output, &en_evpn_arp, - pflow_output_arp_handler); - - engine_add_input(&en_controller_output, &en_dns_cache, - NULL); - engine_add_input(&en_controller_output, &en_lflow_output, - controller_output_lflow_output_handler); - engine_add_input(&en_controller_output, &en_pflow_output, - controller_output_pflow_output_handler); - engine_add_input(&en_controller_output, &en_mac_cache, - controller_output_mac_cache_handler); - engine_add_input(&en_controller_output, &en_bfd_chassis, - controller_output_bfd_chassis_handler); - engine_add_input(&en_controller_output, &en_route_exchange, - controller_output_route_exchange_handler); - engine_add_input(&en_controller_output, &en_garp_rarp, - controller_output_garp_rarp_handler); - - engine_add_input(&en_acl_id, &en_sb_acl_id, NULL); - engine_add_input(&en_controller_output, &en_acl_id, - controller_output_acl_id_handler); - - struct engine_arg engine_arg = { - .sb_idl = ovnsb_idl_loop.idl, - .ovs_idl = ovs_idl_loop.idl, - }; - engine_init(&en_controller_output, &engine_arg); - - engine_ovsdb_node_add_index(&en_sb_chassis, "name", sbrec_chassis_by_name); - engine_ovsdb_node_add_index(&en_sb_multicast_group, "name_datapath", - sbrec_multicast_group_by_name_datapath); - engine_ovsdb_node_add_index(&en_sb_logical_flow, "logical_datapath", - sbrec_logical_flow_by_logical_datapath); - engine_ovsdb_node_add_index(&en_sb_logical_flow, "logical_dp_group", - sbrec_logical_flow_by_logical_dp_group); - engine_ovsdb_node_add_index(&en_sb_port_binding, "name", - sbrec_port_binding_by_name); - engine_ovsdb_node_add_index(&en_sb_port_binding, "key", - sbrec_port_binding_by_key); - engine_ovsdb_node_add_index(&en_sb_port_binding, "datapath", - sbrec_port_binding_by_datapath); - engine_ovsdb_node_add_index(&en_sb_datapath_binding, "key", - sbrec_datapath_binding_by_key); - engine_ovsdb_node_add_index(&en_sb_fdb, "dp_key", - sbrec_fdb_by_dp_key); - engine_ovsdb_node_add_index(&en_sb_mac_binding, "datapath", - sbrec_mac_binding_by_datapath); - engine_ovsdb_node_add_index(&en_sb_static_mac_binding, "datapath", - sbrec_static_mac_binding_by_datapath); - engine_ovsdb_node_add_index(&en_sb_chassis_template_var, "chassis", - sbrec_chassis_template_var_index_by_chassis); - engine_ovsdb_node_add_index(&en_sb_learned_route, "datapath", - sbrec_learned_route_index_by_datapath); - engine_ovsdb_node_add_index(&en_sb_advertised_mac_binding, "datapath", - sbrec_advertised_mac_binding_index_by_dp); - engine_ovsdb_node_add_index(&en_sb_mac_binding, "lport_ip", - sbrec_mac_binding_by_lport_ip); - engine_ovsdb_node_add_index(&en_ovs_flow_sample_collector_set, "id", - ovsrec_flow_sample_collector_set_by_id); - engine_ovsdb_node_add_index(&en_ovs_port, "qos", ovsrec_port_by_qos); - engine_ovsdb_node_add_index(&en_ovs_interface, "name", - ovsrec_interface_by_name); - engine_ovsdb_node_add_index(&en_ovs_queue, "external_ids", - ovsrec_queue_by_external_ids); + inc_proc_ovn_controller_init(&ovnsb_idl_loop, &ovs_idl_loop, + sbrec_chassis_by_name, + sbrec_port_binding_by_name, + sbrec_port_binding_by_key, + sbrec_datapath_binding_by_key, + sbrec_mac_binding_by_lport_ip, + ovsrec_flow_sample_collector_set_by_id, + ovsrec_port_by_qos, + ovsrec_interface_by_name, + ovsrec_queue_by_external_ids); struct ed_type_lflow_output *lflow_output_data = engine_get_internal_data(&en_lflow_output); -- 2.51.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
