On Thu, Nov 27, 2025 at 06:20:33PM +0100, Dumitru Ceara via dev wrote: > 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 >
Looks good to me. Acked-by: Mairtin O'Loingsigh <[email protected]> _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
