On 1/11/24 16:34, num...@ovn.org wrote: > From: Numan Siddique <num...@ovn.org> > > A new engine node "global_config" is added which handles the changes > to NB_Global an SB_Global tables. It also creates these rows if > not present. > > Without the I-P, any changes to the options column of these tables > result in recompute of 'northd' and 'lflow' engine nodes. > > Signed-off-by: Numan Siddique <num...@ovn.org> > ---
Hi Numan, This looks ok overall. I just have a few minor comments, please see below. If you address those feel free to add my ack: Acked-by: Dumitru Ceara <dce...@redhat.com> Thanks, Dumitru > northd/aging.c | 21 +- > northd/automake.mk | 2 + > northd/en-global-config.c | 588 ++++++++++++++++++++++++++++++++++++++ > northd/en-global-config.h | 65 +++++ > northd/en-lflow.c | 11 +- > northd/en-northd.c | 52 ++-- > northd/en-northd.h | 2 +- > northd/en-sync-sb.c | 26 +- > northd/inc-proc-northd.c | 38 ++- > northd/northd.c | 230 +++------------ > northd/northd.h | 24 +- > tests/ovn-northd.at | 256 +++++++++++++++-- > 12 files changed, 1017 insertions(+), 298 deletions(-) > create mode 100644 northd/en-global-config.c > create mode 100644 northd/en-global-config.h > > diff --git a/northd/aging.c b/northd/aging.c > index cdf5f4464e..b76963a2dd 100644 > --- a/northd/aging.c > +++ b/northd/aging.c > @@ -15,6 +15,7 @@ > > #include <config.h> > > +#include "en-global-config.h" > #include "lib/inc-proc-eng.h" > #include "lib/ovn-nb-idl.h" > #include "lib/ovn-sb-idl.h" > @@ -347,15 +348,10 @@ aging_context_handle_timestamp(struct aging_context > *ctx, int64_t timestamp, > static uint32_t > get_removal_limit(struct engine_node *node, const char *name) > { > - const struct nbrec_nb_global_table *nb_global_table = > - EN_OVSDB_GET(engine_get_input("NB_nb_global", node)); > - const struct nbrec_nb_global *nb = > - nbrec_nb_global_table_first(nb_global_table); > - if (!nb) { > - return 0; > - } > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > > - return smap_get_uint(&nb->options, name, 0); > + return smap_get_uint(&global_config->nb_options, name, 0); > } > > /* MAC binding aging */ > @@ -394,11 +390,14 @@ en_mac_binding_aging_run(struct engine_node *node, void > *data OVS_UNUSED) > { > const struct engine_context *eng_ctx = engine_get_context(); > struct northd_data *northd_data = engine_get_input_data("northd", node); > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > + > struct aging_waker *waker = > engine_get_input_data("mac_binding_aging_waker", node); > > if (!eng_ctx->ovnsb_idl_txn || > - !northd_data->features.mac_binding_timestamp || > + !global_config->features.mac_binding_timestamp || > time_msec() < waker->next_wake_msec) { > return; > } > @@ -530,9 +529,11 @@ en_fdb_aging_run(struct engine_node *node, void *data > OVS_UNUSED) > const struct engine_context *eng_ctx = engine_get_context(); > struct northd_data *northd_data = engine_get_input_data("northd", node); > struct aging_waker *waker = engine_get_input_data("fdb_aging_waker", > node); > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > > if (!eng_ctx->ovnsb_idl_txn || > - !northd_data->features.fdb_timestamp || > + !global_config->features.fdb_timestamp || > time_msec() < waker->next_wake_msec) { > return; > } > diff --git a/northd/automake.mk b/northd/automake.mk > index 19abb0dece..d491973a8b 100644 > --- a/northd/automake.mk > +++ b/northd/automake.mk > @@ -8,6 +8,8 @@ northd_ovn_northd_SOURCES = \ > northd/northd.c \ > northd/northd.h \ > northd/ovn-northd.c \ > + northd/en-global-config.c \ > + northd/en-global-config.h \ > northd/en-northd.c \ > northd/en-northd.h \ > northd/en-lflow.c \ > diff --git a/northd/en-global-config.c b/northd/en-global-config.c > new file mode 100644 > index 0000000000..0d218f2ab5 > --- /dev/null > +++ b/northd/en-global-config.c > @@ -0,0 +1,588 @@ > +/* > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at: > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#include <config.h> > + > +#include <getopt.h> > +#include <stdlib.h> > +#include <stdio.h> > + > +/* OVS includes */ > +#include "openvswitch/vlog.h" > + > +/* OVN includes */ > +#include "debug.h" > +#include "en-global-config.h" > +#include "include/ovn/features.h" > +#include "ipam.h" > +#include "lib/ovn-nb-idl.h" > +#include "lib/ovn-sb-idl.h" > +#include "northd.h" > + > + > +VLOG_DEFINE_THIS_MODULE(en_global_config); > + > +/* static function declarations. */ > +static void northd_enable_all_features(struct ed_type_global_config *); > +static void build_chassis_features(const struct sbrec_chassis_table *, > + struct chassis_features *); > +static bool chassis_features_changed(const struct chassis_features *, > + const struct chassis_features *); > +static bool config_out_of_sync(const struct smap *config, > + const struct smap *saved_config, > + const char *key, bool must_be_present); > +static bool check_nb_options_out_of_sync(const struct nbrec_nb_global *, > + struct ed_type_global_config *); > +static void update_sb_config_options_to_sbrec(struct ed_type_global_config *, > + const struct sbrec_sb_global > *); > + > +void * > +en_global_config_init(struct engine_node *node OVS_UNUSED, > + struct engine_arg *args OVS_UNUSED) > +{ > + struct ed_type_global_config *data = xzalloc(sizeof *data); > + smap_init(&data->nb_options); > + smap_init(&data->sb_options); > + northd_enable_all_features(data); > + return data; > +} > + > +void > +en_global_config_run(struct engine_node *node , void *data) > +{ > + const struct engine_context *eng_ctx = engine_get_context(); > + if (!eng_ctx->ovnnb_idl_txn || !eng_ctx->ovnsb_idl_txn) { > + return; > + } > + > + const struct nbrec_nb_global_table *nb_global_table = > + EN_OVSDB_GET(engine_get_input("NB_nb_global", node)); > + const struct sbrec_sb_global_table *sb_global_table = > + EN_OVSDB_GET(engine_get_input("SB_sb_global", node)); > + const struct sbrec_chassis_table *sbrec_chassis_table = > + EN_OVSDB_GET(engine_get_input("SB_chassis", node)); > + > + en_global_config_clear_tracked_data(data); > + We shouldn't have to do this, right? It should be automatically done by the I-P engine. > + struct ed_type_global_config *config_data = data; > + > + /* Sync ipsec configuration. > + * Copy nb_cfg from northbound to southbound database. > + * Also set up to update sb_cfg once our southbound transaction commits. > */ > + const struct nbrec_nb_global *nb = > + nbrec_nb_global_table_first(nb_global_table); > + if (!nb) { > + nb = nbrec_nb_global_insert(eng_ctx->ovnnb_idl_txn); > + } > + > + const char *mac_addr_prefix = set_mac_prefix(smap_get(&nb->options, > + "mac_prefix")); > + > + const char *monitor_mac = smap_get(&nb->options, "svc_monitor_mac"); > + if (monitor_mac) { > + if (eth_addr_from_string(monitor_mac, > + &config_data->svc_monitor_mac_ea)) { > + snprintf(config_data->svc_monitor_mac, > + sizeof config_data->svc_monitor_mac, > + ETH_ADDR_FMT, > + ETH_ADDR_ARGS(config_data->svc_monitor_mac_ea)); > + } else { > + monitor_mac = NULL; > + } > + } > + > + struct smap *options = &config_data->nb_options; > + smap_destroy(options); > + smap_clone(options, &nb->options); > + > + smap_replace(options, "mac_prefix", mac_addr_prefix); > + > + if (!monitor_mac) { > + eth_addr_random(&config_data->svc_monitor_mac_ea); > + snprintf(config_data->svc_monitor_mac, > + sizeof config_data->svc_monitor_mac, ETH_ADDR_FMT, > + ETH_ADDR_ARGS(config_data->svc_monitor_mac_ea)); > + smap_replace(options, "svc_monitor_mac", > + config_data->svc_monitor_mac); > + } > + > + char *max_tunid = xasprintf("%d", > + get_ovn_max_dp_key_local(sbrec_chassis_table)); > + smap_replace(options, "max_tunid", max_tunid); > + free(max_tunid); > + > + char *ovn_internal_version = ovn_get_internal_version(); > + if (strcmp(ovn_internal_version, > + smap_get_def(options, "northd_internal_version", ""))) { > + smap_replace(options, "northd_internal_version", > + ovn_internal_version); > + config_data->ovn_internal_version_changed = true; > + } else { > + config_data->ovn_internal_version_changed = false; > + } > + > + free(ovn_internal_version); > + > + if (!smap_equal(&nb->options, options)) { > + nbrec_nb_global_verify_options(nb); > + nbrec_nb_global_set_options(nb, options); > + } > + > + if (smap_get_bool(&nb->options, "ignore_chassis_features", false)) { > + northd_enable_all_features(config_data); > + } else { > + build_chassis_features(sbrec_chassis_table, &config_data->features); > + } > + > + init_debug_config(nb); > + > + const struct sbrec_sb_global *sb = > + sbrec_sb_global_table_first(sb_global_table); > + if (!sb) { > + sb = sbrec_sb_global_insert(eng_ctx->ovnsb_idl_txn); > + } > + if (nb->ipsec != sb->ipsec) { > + sbrec_sb_global_set_ipsec(sb, nb->ipsec); > + } > + > + /* Set up SB_Global (depends on chassis features). */ > + update_sb_config_options_to_sbrec(config_data, sb); > + > + engine_set_node_state(node, EN_UPDATED); > +} > + > +void en_global_config_cleanup(void *data OVS_UNUSED) > +{ > + struct ed_type_global_config *config_data = data; > + smap_destroy(&config_data->nb_options); > + smap_destroy(&config_data->sb_options); > + destroy_debug_config(); > +} > + > +void > +en_global_config_clear_tracked_data(void *data) > +{ > + struct ed_type_global_config *config_data = data; > + config_data->tracked = false; > + config_data->tracked_data.nb_options_changed = false; > + config_data->tracked_data.chassis_features_changed = false; > +} > + > +bool > +global_config_nb_global_handler(struct engine_node *node, void *data) > +{ > + const struct nbrec_nb_global_table *nb_global_table = > + EN_OVSDB_GET(engine_get_input("NB_nb_global", node)); > + const struct sbrec_sb_global_table *sb_global_table = > + EN_OVSDB_GET(engine_get_input("SB_sb_global", node)); > + > + const struct nbrec_nb_global *nb = > + nbrec_nb_global_table_first(nb_global_table); > + if (!nb) { > + return false; > + } > + > + const struct sbrec_sb_global *sb = > + sbrec_sb_global_table_first(sb_global_table); > + if (!sb) { > + return false; > + } > + > + /* We are only interested in ipsec and options column. */ > + bool changes_relevant = false; > + if (nbrec_nb_global_is_updated(nb, NBREC_NB_GLOBAL_COL_IPSEC) > + || nbrec_nb_global_is_updated(nb, NBREC_NB_GLOBAL_COL_OPTIONS)) { > + changes_relevant = true; > + } > + > + if (!changes_relevant) { > + return true; > + } We can do the simpler: if (!nbrec_nb_global_is_updated(nb, NBREC_NB_GLOBAL_COL_IPSEC) && !nbrec_nb_global_is_updated(nb, NBREC_NB_GLOBAL_COL_OPTIONS)) { return false; } > + > + const struct engine_context *eng_ctx = engine_get_context(); > + if (!eng_ctx->ovnsb_idl_txn) { > + return false; > + } This is never hit, right? > + > + if (nb->ipsec != sb->ipsec) { > + sbrec_sb_global_set_ipsec(sb, nb->ipsec); > + } > + > + struct ed_type_global_config *config_data = data; > + config_data->tracked = true; > + > + if (smap_equal(&nb->options, &config_data->nb_options)) { > + return true; > + } > + > + /* Return false if an option is out of sync and requires updating the > + * NB config. (Like svc_monitor_mac, max_tunid and mac_prefix). */ > + /* Check if svc_monitor_mac has changed or not. */ > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "svc_monitor_mac", true)) { > + return false; > + } > + > + /* Check if max_tunid has changed or not. */ > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "max_tunid", true)) { > + return false; > + } > + > + /* Check if mac_prefix has changed or not. */ > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "mac_prefix", true)) { > + return false; > + } > + > + /* Check if ignore_chassis_features has changed or not. */ > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "ignore_chassis_features", false)) { > + return false; > + } > + > + /* Check if northd_internal_version has changed or not. */ > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "northd_internal_version", false)) { > + return false; > + } > + > + if (check_nb_options_out_of_sync(nb, config_data)) { > + config_data->tracked_data.nb_options_changed = true; > + } > + > + smap_destroy(&config_data->nb_options); > + smap_clone(&config_data->nb_options, &nb->options); > + > + update_sb_config_options_to_sbrec(config_data, sb); > + > + engine_set_node_state(node, EN_UPDATED); > + return true; > +} > + > +bool > +global_config_sb_global_handler(struct engine_node *node, void *data) > +{ > + const struct sbrec_sb_global_table *sb_global_table = > + EN_OVSDB_GET(engine_get_input("SB_sb_global", node)); > + > + const struct sbrec_sb_global *sb = > + sbrec_sb_global_table_first(sb_global_table); > + if (!sb) { > + return false; > + } > + > + struct ed_type_global_config *config_data = data; > + > + if (!smap_equal(&sb->options, &config_data->sb_options)) { > + return false; > + } > + > + /* No need to update the engine node. */ > + return true; > +} > + > +bool > +global_config_sb_chassis_handler(struct engine_node *node, void *data) > +{ > + struct ed_type_global_config *config_data = data; > + > + const struct sbrec_chassis_table *sbrec_chassis_table = > + EN_OVSDB_GET(engine_get_input("SB_chassis", node)); > + const struct sbrec_chassis *chassis; > + > + SBREC_CHASSIS_TABLE_FOR_EACH_TRACKED (chassis, sbrec_chassis_table) { > + if (sbrec_chassis_is_new(chassis) > + || sbrec_chassis_is_deleted(chassis) > + || sbrec_chassis_is_updated(chassis, > + SBREC_CHASSIS_COL_ENCAPS)) { > + return false; > + } > + > + for (size_t i = 0; i < chassis->n_encaps; i++) { > + if (sbrec_encap_row_get_seqno(chassis->encaps[i], > + OVSDB_IDL_CHANGE_MODIFY) > 0) { > + return false; > + } > + } > + } > + > + if (smap_get_bool(&config_data->nb_options, "ignore_chassis_features", > + false)) { > + return true; > + } > + > + bool reevaluate_chassis_features = false; > + > + /* Check and evaluate chassis features. */ > + SBREC_CHASSIS_TABLE_FOR_EACH_TRACKED (chassis, sbrec_chassis_table) { > + if (sbrec_chassis_is_updated(chassis, > + SBREC_CHASSIS_COL_OTHER_CONFIG)) { > + reevaluate_chassis_features = true; > + break; > + } > + } > + > + if (!reevaluate_chassis_features) { > + return true; > + } > + > + struct chassis_features present_features = config_data->features; > + > + /* Enable all features before calling build_chassis_features() as > + * build_chassis_features() only sets the feature flags to false. */ > + northd_enable_all_features(config_data); > + build_chassis_features(sbrec_chassis_table, &config_data->features); > + > + if (chassis_features_changed(&present_features, &config_data->features)) > { > + config_data->tracked_data.chassis_features_changed = true; > + config_data->tracked = true; > + engine_set_node_state(node, EN_UPDATED); > + } > + > + return true; > +} > + > +/* generic global config handler for any engine node which has global_config > + * has an input node . */ > +bool > +node_global_config_handler(struct engine_node *node, void *data OVS_UNUSED) > +{ > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > + > + if (!global_config->tracked > + || global_config->tracked_data.chassis_features_changed > + || global_config->tracked_data.nb_options_changed) { > + return false; > + } > + > + return true; > +} > + > +/* static functions. */ > +static void > +northd_enable_all_features(struct ed_type_global_config *data) > +{ > + data->features = (struct chassis_features) { > + .ct_no_masked_label = true, > + .mac_binding_timestamp = true, > + .ct_lb_related = true, > + .fdb_timestamp = true, > + .ls_dpg_column = true, > + }; > +} > + > +static void > +build_chassis_features(const struct sbrec_chassis_table *sbrec_chassis_table, > + struct chassis_features *chassis_features) > +{ > + const struct sbrec_chassis *chassis; > + > + SBREC_CHASSIS_TABLE_FOR_EACH (chassis, sbrec_chassis_table) { > + /* Only consider local AZ chassis. Remote ones don't install > + * flows generated by the local northd. > + */ > + if (smap_get_bool(&chassis->other_config, "is-remote", false)) { > + continue; > + } > + > + bool ct_no_masked_label = > + smap_get_bool(&chassis->other_config, > + OVN_FEATURE_CT_NO_MASKED_LABEL, > + false); > + if (!ct_no_masked_label && chassis_features->ct_no_masked_label) { > + chassis_features->ct_no_masked_label = false; > + } > + > + bool mac_binding_timestamp = > + smap_get_bool(&chassis->other_config, > + OVN_FEATURE_MAC_BINDING_TIMESTAMP, > + false); > + if (!mac_binding_timestamp && > + chassis_features->mac_binding_timestamp) { > + chassis_features->mac_binding_timestamp = false; > + } > + > + bool ct_lb_related = > + smap_get_bool(&chassis->other_config, > + OVN_FEATURE_CT_LB_RELATED, > + false); > + if (!ct_lb_related && > + chassis_features->ct_lb_related) { > + chassis_features->ct_lb_related = false; > + } > + > + bool fdb_timestamp = > + smap_get_bool(&chassis->other_config, > + OVN_FEATURE_FDB_TIMESTAMP, > + false); > + if (!fdb_timestamp && > + chassis_features->fdb_timestamp) { > + chassis_features->fdb_timestamp = false; > + } > + > + bool ls_dpg_column = > + smap_get_bool(&chassis->other_config, > + OVN_FEATURE_LS_DPG_COLUMN, > + false); > + if (!ls_dpg_column && > + chassis_features->ls_dpg_column) { > + chassis_features->ls_dpg_column = false; > + } > + } > +} > + > +static bool > +config_out_of_sync(const struct smap *config, const struct smap > *saved_config, > + const char *key, bool must_be_present) > +{ > + const char *value = smap_get(config, key); > + if (!value && must_be_present) { > + return true; > + } > + > + const char *saved_value = smap_get(saved_config, key); > + if (!saved_value && must_be_present) { > + return true; > + } > + > + if (!value && !saved_value) { > + return false; > + } > + > + if ((!value && saved_value) || (value && !saved_value)) { No need for the inner parenthesis. OTOH isn't it equivalent to just do the following here? if (!value || !saved_value) { return true; } > + return true; > + } > + > + return strcmp(value, saved_value); > +} > + > +static bool > +check_nb_options_out_of_sync(const struct nbrec_nb_global *nb, > + struct ed_type_global_config *config_data) > +{ > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "mac_binding_removal_limit", false)) { > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "fdb_removal_limit", false)) { > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "controller_event", false)) { > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "ignore_lsp_down", false)) { > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "use_ct_inv_match", false)) { > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "default_acl_drop", false)) { > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "debug_drop_domain_id", false)) { > + init_debug_config(nb); > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "debug_drop_collector_set", false)) { > + init_debug_config(nb); > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "use_common_zone", false)) { > + return true; > + } > + > + if (config_out_of_sync(&nb->options, &config_data->nb_options, > + "install_ls_lb_from_router", false)) { > + return true; > + } > + > + return false; > +} > + > +static void > +update_sb_config_options_to_sbrec(struct ed_type_global_config *config_data, > + const struct sbrec_sb_global *sb) > +{ > + struct smap *options = &config_data->sb_options; > + > + smap_destroy(options); > + smap_clone(options, &config_data->nb_options); > + > + /* Inform ovn-controllers whether LB flows will use ct_mark (i.e., only > + * if all chassis support it). If not explicitly present in the database > + * the default value to be used for this option is 'true'. > + */ > + if (!config_data->features.ct_no_masked_label) { > + smap_replace(options, "lb_hairpin_use_ct_mark", "false"); > + } else { > + smap_remove(options, "lb_hairpin_use_ct_mark"); > + } > + > + /* Hackaround SB_global.options overwrite by NB_Global.options for > + * 'sbctl_probe_interval' option. > + */ > + const char *sip = smap_get(&sb->options, "sbctl_probe_interval"); > + if (sip) { > + smap_replace(options, "sbctl_probe_interval", sip); > + } > + > + if (!smap_equal(&sb->options, options)) { > + sbrec_sb_global_set_options(sb, options); > + } > +} > + > +static bool > +chassis_features_changed(const struct chassis_features *present, > + const struct chassis_features *updated) > +{ > + if (present->ct_no_masked_label != updated->ct_no_masked_label) { > + return true; > + } > + > + if (present->mac_binding_timestamp != updated->mac_binding_timestamp) { > + return true; > + } > + > + if (present->ct_lb_related != updated->ct_lb_related) { > + return true; > + } > + > + if (present->fdb_timestamp != updated->fdb_timestamp) { > + return true; > + } > + > + if (present->ls_dpg_column != updated->ls_dpg_column) { > + return true; > + } > + > + return false; > +} > diff --git a/northd/en-global-config.h b/northd/en-global-config.h > new file mode 100644 > index 0000000000..436bc7fa35 > --- /dev/null > +++ b/northd/en-global-config.h > @@ -0,0 +1,65 @@ > +#ifndef EN_GLOBAL_CONFIG_H > +#define EN_GLOBAL_CONFIG_H 1 > + > +#include <config.h> > + > +/* OVS includes. */ > +#include "lib/packets.h" > +#include "lib/smap.h" > + > +/* OVN includes. */ > +#include "lib/inc-proc-eng.h" > + > +struct nbrec_nb_global; > +struct sbrec_sb_global; > + > +struct chassis_features { > + bool ct_no_masked_label; > + bool mac_binding_timestamp; > + bool ct_lb_related; > + bool fdb_timestamp; > + bool ls_dpg_column; > +}; > + > +struct global_config_tracked_data { > + bool nb_options_changed; > + bool chassis_features_changed; > +}; > + > +/* struct which maintains the data of the engine node global_config. */ > +struct ed_type_global_config { > + struct smap nb_options; > + struct smap sb_options; > + const struct nbrec_nb_global *nb_global; > + const struct sbrec_sb_global *sb_global; > + > + /* MAC allocated for service monitor usage. Just one mac is allocated > + * for this purpose and ovn-controller's on each chassis will make use > + * of this mac when sending out the packets to monitor the services > + * defined in Service_Monitor Southbound table. Since these packets > + * are locally handled, having just one mac is good enough. */ > + char svc_monitor_mac[ETH_ADDR_STRLEN + 1]; > + struct eth_addr svc_monitor_mac_ea; > + > + struct chassis_features features; > + > + bool ovn_internal_version_changed; > + > + bool tracked; > + struct global_config_tracked_data tracked_data; > +}; > + > +void *en_global_config_init(struct engine_node *, struct engine_arg *); > +void en_global_config_run(struct engine_node *, void *data); > +void en_global_config_cleanup(void *data); > +void en_global_config_clear_tracked_data(void *data); > + > +bool global_config_nb_global_handler(struct engine_node *, void *data); > +bool global_config_sb_global_handler(struct engine_node *, void *data); > +bool global_config_sb_chassis_handler(struct engine_node *, void *data); > + > +/* generic global config handler for any engine node which has global_config > + * has an input node . */ > +bool node_global_config_handler(struct engine_node *, void *data); > + > +#endif /* EN_GLOBAL_CONFIG_H */ > diff --git a/northd/en-lflow.c b/northd/en-lflow.c > index f51ee0d2b7..21e8131562 100644 > --- a/northd/en-lflow.c > +++ b/northd/en-lflow.c > @@ -18,6 +18,7 @@ > #include <stdlib.h> > #include <stdio.h> > > +#include "en-global-config.h" > #include "en-lflow.h" > #include "en-lr-nat.h" > #include "en-lr-stateful.h" > @@ -77,10 +78,14 @@ lflow_get_input_data(struct engine_node *node, > lflow_input->meter_groups = &sync_meters_data->meter_groups; > lflow_input->lb_datapaths_map = &northd_data->lb_datapaths_map; > lflow_input->svc_monitor_map = &northd_data->svc_monitor_map; > - lflow_input->features = &northd_data->features; > - lflow_input->ovn_internal_version_changed = > - northd_data->ovn_internal_version_changed; > lflow_input->bfd_connections = NULL; > + > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > + lflow_input->features = &global_config->features; > + lflow_input->ovn_internal_version_changed = > + global_config->ovn_internal_version_changed; Nit: indentation > + lflow_input->svc_monitor_mac = global_config->svc_monitor_mac; > } > > void en_lflow_run(struct engine_node *node, void *data) > diff --git a/northd/en-northd.c b/northd/en-northd.c > index 5143603f39..4479b4aff2 100644 > --- a/northd/en-northd.c > +++ b/northd/en-northd.c > @@ -19,6 +19,7 @@ > #include <stdio.h> > > #include "coverage.h" > +#include "en-global-config.h" > #include "en-northd.h" > #include "en-lb-data.h" > #include "lib/inc-proc-eng.h" > @@ -65,8 +66,6 @@ northd_get_input_data(struct engine_node *node, > engine_get_input("SB_fdb", node), > "sbrec_fdb_by_dp_and_port"); > > - input_data->nbrec_nb_global_table = > - EN_OVSDB_GET(engine_get_input("NB_nb_global", node)); > input_data->nbrec_logical_switch_table = > EN_OVSDB_GET(engine_get_input("NB_logical_switch", node)); > input_data->nbrec_logical_router_table = > @@ -78,8 +77,6 @@ northd_get_input_data(struct engine_node *node, > input_data->nbrec_mirror_table = > EN_OVSDB_GET(engine_get_input("NB_mirror", node)); > > - input_data->sbrec_sb_global_table = > - EN_OVSDB_GET(engine_get_input("SB_sb_global", node)); > input_data->sbrec_datapath_binding_table = > EN_OVSDB_GET(engine_get_input("SB_datapath_binding", node)); > input_data->sbrec_port_binding_table = > @@ -109,6 +106,14 @@ northd_get_input_data(struct engine_node *node, > engine_get_input_data("lb_data", node); > input_data->lbs = &lb_data->lbs; > input_data->lbgrps = &lb_data->lbgrps; > + > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > + input_data->nb_options = &global_config->nb_options; > + input_data->sb_options = &global_config->sb_options; > + input_data->svc_monitor_mac = global_config->svc_monitor_mac; > + input_data->svc_monitor_mac_ea = global_config->svc_monitor_mac_ea; > + input_data->features = &global_config->features; > } > > void > @@ -129,31 +134,6 @@ en_northd_run(struct engine_node *node, void *data) > eng_ctx->ovnsb_idl_txn); > stopwatch_stop(OVNNB_DB_RUN_STOPWATCH_NAME, time_msec()); > engine_set_node_state(node, EN_UPDATED); > - > -} > - > -bool > -northd_nb_nb_global_handler(struct engine_node *node, > - void *data OVS_UNUSED) > -{ > - const struct nbrec_nb_global_table *nb_global_table > - = EN_OVSDB_GET(engine_get_input("NB_nb_global", node)); > - > - const struct nbrec_nb_global *nb = > - nbrec_nb_global_table_first(nb_global_table); > - > - if (!nb) { > - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > - VLOG_WARN_RL(&rl, "NB_Global is updated but has no record."); > - return false; > - } > - > - /* We care about the 'options' and 'ipsec' columns only. */ > - if (nbrec_nb_global_is_updated(nb, NBREC_NB_GLOBAL_COL_OPTIONS) || > - nbrec_nb_global_is_updated(nb, NBREC_NB_GLOBAL_COL_IPSEC)) { > - return false; > - } > - return true; > } > > bool > @@ -242,6 +222,20 @@ northd_lb_data_handler(struct engine_node *node, void > *data) > return true; > } > > +bool > +northd_global_config_handler(struct engine_node *node, void *data OVS_UNUSED) > +{ > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > + > + if (!global_config->tracked > + || global_config->tracked_data.nb_options_changed) { > + return false; > + } > + > + return true; > +} > + > void > *en_northd_init(struct engine_node *node OVS_UNUSED, > struct engine_arg *arg OVS_UNUSED) > diff --git a/northd/en-northd.h b/northd/en-northd.h > index 5a88871760..9b7bda32aa 100644 > --- a/northd/en-northd.h > +++ b/northd/en-northd.h > @@ -14,7 +14,7 @@ void *en_northd_init(struct engine_node *node OVS_UNUSED, > struct engine_arg *arg); > void en_northd_cleanup(void *data); > void en_northd_clear_tracked_data(void *data); > -bool northd_nb_nb_global_handler(struct engine_node *, void *data > OVS_UNUSED); > +bool northd_global_config_handler(struct engine_node *, void *data > OVS_UNUSED); > bool northd_nb_logical_switch_handler(struct engine_node *, void *data); > bool northd_nb_logical_router_handler(struct engine_node *, void *data); > bool northd_sb_port_binding_handler(struct engine_node *, void *data); > diff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c > index 80f3621bb9..0c8428c61d 100644 > --- a/northd/en-sync-sb.c > +++ b/northd/en-sync-sb.c > @@ -24,6 +24,7 @@ > > /* OVN includes. */ > #include "en-lr-nat.h" > +#include "en-global-config.h" > #include "en-lr-stateful.h" > #include "en-sync-sb.h" > #include "lb.h" > @@ -46,7 +47,8 @@ static void sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > const struct nbrec_address_set_table *, > const struct nbrec_port_group_table *, > const struct sbrec_address_set_table *, > - const struct lr_stateful_table *); > + const struct lr_stateful_table *, > + const char *svc_monitor_macp); > static const struct sbrec_address_set *sb_address_set_lookup_by_name( > struct ovsdb_idl_index *, const char *name); > static void update_sb_addr_set(struct sorted_array *, > @@ -128,9 +130,12 @@ en_sync_to_sb_addr_set_run(struct engine_node *node, > void *data OVS_UNUSED) > const struct engine_context *eng_ctx = engine_get_context(); > const struct ed_type_lr_stateful *lr_stateful_data = > engine_get_input_data("lr_stateful", node); > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > sync_addr_sets(eng_ctx->ovnsb_idl_txn, nb_address_set_table, > nb_port_group_table, sb_address_set_table, > - &lr_stateful_data->table); > + &lr_stateful_data->table, > + global_config->svc_monitor_mac); > > engine_set_node_state(node, EN_UPDATED); > } > @@ -282,6 +287,8 @@ en_sync_to_sb_lb_run(struct engine_node *node, void > *data_) > EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); > const struct sbrec_logical_dp_group_table *sb_dpgrp_table = > EN_OVSDB_GET(engine_get_input("SB_logical_dp_group", node)); > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > const struct engine_context *eng_ctx = engine_get_context(); > struct ed_type_sync_to_sb_lb_data *data = data_; > > @@ -292,7 +299,7 @@ en_sync_to_sb_lb_run(struct engine_node *node, void > *data_) > &northd_data->lb_datapaths_map, > &northd_data->ls_datapaths, > &northd_data->lr_datapaths, > - &northd_data->features); > + &global_config->features); > > engine_set_node_state(node, EN_UPDATED); > } > @@ -327,12 +334,14 @@ sync_to_sb_lb_northd_handler(struct engine_node *node, > void *data_) > EN_OVSDB_GET(engine_get_input("SB_logical_dp_group", node)); > const struct sbrec_load_balancer_table *sb_lb_table = > EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); > + struct ed_type_global_config *global_config = > + engine_get_input_data("global_config", node); > struct ed_type_sync_to_sb_lb_data *data = data_; > > if (!sync_changed_lbs(&data->sb_lbs, eng_ctx->ovnsb_idl_txn, sb_lb_table, > sb_dpgrp_table, &nd->trk_data.trk_lbs, > &nd->ls_datapaths, &nd->lr_datapaths, > - &nd->features)) { > + &global_config->features)) { > return false; > } > > @@ -457,7 +466,8 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > const struct nbrec_address_set_table *nb_address_set_table, > const struct nbrec_port_group_table *nb_port_group_table, > const struct sbrec_address_set_table *sb_address_set_table, > - const struct lr_stateful_table *lr_statefuls) > + const struct lr_stateful_table *lr_statefuls, > + const char *svc_monitor_macp) > { > struct shash sb_address_sets = SHASH_INITIALIZER(&sb_address_sets); > > @@ -468,8 +478,10 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > } > > /* Service monitor MAC. */ > - const char *svc_monitor_macp = northd_get_svc_monitor_mac(); > - struct sorted_array svc = sorted_array_create(&svc_monitor_macp, 1, > false); > + struct sorted_array svc = { > + .arr = &svc_monitor_macp, > + .n = 1, > + }; I'd prefer we don't manually initialize sorted_array fields. What was wrong with the previous way of initializing? struct sorted_array svc = sorted_array_create(&svc_monitor_macp, 1, false); > sync_addr_set(ovnsb_txn, "svc_monitor_mac", &svc, &sb_address_sets); > sorted_array_destroy(&svc); > > diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c > index d215c7792b..e1073812c8 100644 > --- a/northd/inc-proc-northd.c > +++ b/northd/inc-proc-northd.c > @@ -30,6 +30,7 @@ > #include "openvswitch/poll-loop.h" > #include "openvswitch/vlog.h" > #include "inc-proc-northd.h" > +#include "en-global-config.h" > #include "en-lb-data.h" > #include "en-lr-stateful.h" > #include "en-lr-nat.h" > @@ -149,6 +150,7 @@ static ENGINE_NODE(fdb_aging, "fdb_aging"); > static ENGINE_NODE(fdb_aging_waker, "fdb_aging_waker"); > static ENGINE_NODE(sync_to_sb_lb, "sync_to_sb_lb"); > static ENGINE_NODE(sync_to_sb_pb, "sync_to_sb_pb"); > +static ENGINE_NODE_WITH_CLEAR_TRACK_DATA(global_config, "global_config"); > static ENGINE_NODE_WITH_CLEAR_TRACK_DATA(lb_data, "lb_data"); > static ENGINE_NODE_WITH_CLEAR_TRACK_DATA(lr_nat, "lr_nat"); > static ENGINE_NODE_WITH_CLEAR_TRACK_DATA(lr_stateful, "lr_stateful"); > @@ -168,11 +170,17 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > engine_add_input(&en_lb_data, &en_nb_logical_router, > lb_data_logical_router_handler); > > + engine_add_input(&en_global_config, &en_nb_nb_global, > + global_config_nb_global_handler); > + engine_add_input(&en_global_config, &en_sb_sb_global, > + global_config_sb_global_handler); > + engine_add_input(&en_global_config, &en_sb_chassis, > + global_config_sb_chassis_handler); > + > engine_add_input(&en_northd, &en_nb_mirror, NULL); > engine_add_input(&en_northd, &en_nb_static_mac_binding, NULL); > engine_add_input(&en_northd, &en_nb_chassis_template_var, NULL); > > - engine_add_input(&en_northd, &en_sb_sb_global, NULL); > engine_add_input(&en_northd, &en_sb_chassis, NULL); > engine_add_input(&en_northd, &en_sb_mirror, NULL); > engine_add_input(&en_northd, &en_sb_meter, NULL); > @@ -184,6 +192,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > engine_add_input(&en_northd, &en_sb_fdb, NULL); > engine_add_input(&en_northd, &en_sb_static_mac_binding, NULL); > engine_add_input(&en_northd, &en_sb_chassis_template_var, NULL); > + engine_add_input(&en_northd, &en_global_config, > + northd_global_config_handler); > > /* northd engine node uses the sb mac binding table to > * cleanup mac binding entries for deleted logical ports > @@ -198,8 +208,6 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > > engine_add_input(&en_northd, &en_sb_port_binding, > northd_sb_port_binding_handler); > - engine_add_input(&en_northd, &en_nb_nb_global, > - northd_nb_nb_global_handler); > engine_add_input(&en_northd, &en_nb_logical_switch, > northd_nb_logical_switch_handler); > engine_add_input(&en_northd, &en_nb_logical_router, > @@ -217,15 +225,17 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > engine_add_input(&en_ls_stateful, &en_port_group, > ls_stateful_port_group_handler); > > - engine_add_input(&en_mac_binding_aging, &en_nb_nb_global, NULL); > engine_add_input(&en_mac_binding_aging, &en_sb_mac_binding, NULL); > engine_add_input(&en_mac_binding_aging, &en_northd, NULL); > engine_add_input(&en_mac_binding_aging, &en_mac_binding_aging_waker, > NULL); > + engine_add_input(&en_mac_binding_aging, &en_global_config, > + node_global_config_handler); > > - engine_add_input(&en_fdb_aging, &en_nb_nb_global, NULL); > engine_add_input(&en_fdb_aging, &en_sb_fdb, NULL); > engine_add_input(&en_fdb_aging, &en_northd, NULL); > engine_add_input(&en_fdb_aging, &en_fdb_aging_waker, NULL); > + engine_add_input(&en_fdb_aging, &en_global_config, > + node_global_config_handler); > > engine_add_input(&en_sync_meters, &en_nb_acl, NULL); > engine_add_input(&en_sync_meters, &en_nb_meter, NULL); > @@ -239,18 +249,22 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > engine_add_input(&en_lflow, &en_sb_multicast_group, NULL); > engine_add_input(&en_lflow, &en_sb_igmp_group, NULL); > engine_add_input(&en_lflow, &en_sb_logical_dp_group, NULL); > + engine_add_input(&en_lflow, &en_global_config, > + node_global_config_handler); > engine_add_input(&en_lflow, &en_northd, lflow_northd_handler); > engine_add_input(&en_lflow, &en_port_group, lflow_port_group_handler); > engine_add_input(&en_lflow, &en_lr_stateful, lflow_lr_stateful_handler); > engine_add_input(&en_lflow, &en_ls_stateful, lflow_ls_stateful_handler); > > + engine_add_input(&en_sync_to_sb_addr_set, &en_northd, NULL); > + engine_add_input(&en_sync_to_sb_addr_set, &en_lr_stateful, NULL); > + engine_add_input(&en_sync_to_sb_addr_set, &en_sb_address_set, NULL); > engine_add_input(&en_sync_to_sb_addr_set, &en_nb_address_set, > sync_to_sb_addr_set_nb_address_set_handler); > engine_add_input(&en_sync_to_sb_addr_set, &en_nb_port_group, > sync_to_sb_addr_set_nb_port_group_handler); > - engine_add_input(&en_sync_to_sb_addr_set, &en_northd, NULL); > - engine_add_input(&en_sync_to_sb_addr_set, &en_lr_stateful, NULL); > - engine_add_input(&en_sync_to_sb_addr_set, &en_sb_address_set, NULL); > + engine_add_input(&en_sync_to_sb_addr_set, &en_global_config, > + node_global_config_handler); > > engine_add_input(&en_port_group, &en_nb_port_group, > port_group_nb_port_group_handler); > @@ -260,6 +274,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > * table too (because of the explicit dependency in the schema). */ > engine_add_input(&en_port_group, &en_northd, engine_noop_handler); > > + engine_add_input(&en_sync_to_sb_lb, &en_global_config, > + node_global_config_handler); > engine_add_input(&en_sync_to_sb_lb, &en_northd, > sync_to_sb_lb_northd_handler); > engine_add_input(&en_sync_to_sb_lb, &en_sb_load_balancer, > @@ -365,11 +381,11 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > "sbrec_fdb_by_dp_and_port", > sbrec_fdb_by_dp_and_port); > > - struct northd_data *northd_data = > - engine_get_internal_data(&en_northd); > + struct ed_type_global_config *global_config = > + engine_get_internal_data(&en_global_config); > unixctl_command_register("debug/chassis-features-list", "", 0, 0, > chassis_features_list, > - &northd_data->features); > + &global_config->features); > } > > /* Returns true if the incremental processing ended up updating nodes. */ > diff --git a/northd/northd.c b/northd/northd.c > index d21a070fdd..159409ea48 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -45,6 +45,7 @@ > #include "lflow-mgr.h" > #include "memory.h" > #include "northd.h" > +#include "en-global-config.h" > #include "en-lb-data.h" > #include "en-lr-nat.h" > #include "en-lr-stateful.h" > @@ -79,14 +80,6 @@ static bool install_ls_lb_from_router; > /* Use common zone for SNAT and DNAT if this option is set to "true". */ > static bool use_common_zone = false; > > -/* MAC allocated for service monitor usage. Just one mac is allocatedg5534 > - * for this purpose and ovn-controller's on each chassis will make use > - * of this mac when sending out the packets to monitor the services > - * defined in Service_Monitor Southbound table. Since these packets > - * all locally handled, having just one mac is good enough. */ > -static char svc_monitor_mac[ETH_ADDR_STRLEN + 1]; > -static struct eth_addr svc_monitor_mac_ea; > - > /* If this option is 'true' northd will make use of ct.inv match fields. > * Otherwise, it will avoid using it. The default is true. */ > static bool use_ct_inv_match = true; > @@ -297,66 +290,6 @@ ovn_stage_to_datapath_type(enum ovn_stage stage) > } > } > > -static void > -build_chassis_features(const struct sbrec_chassis_table *sbrec_chassis_table, > - struct chassis_features *chassis_features) > -{ > - const struct sbrec_chassis *chassis; > - > - SBREC_CHASSIS_TABLE_FOR_EACH (chassis, sbrec_chassis_table) { > - /* Only consider local AZ chassis. Remote ones don't install > - * flows generated by the local northd. > - */ > - if (smap_get_bool(&chassis->other_config, "is-remote", false)) { > - continue; > - } > - > - bool ct_no_masked_label = > - smap_get_bool(&chassis->other_config, > - OVN_FEATURE_CT_NO_MASKED_LABEL, > - false); > - if (!ct_no_masked_label && chassis_features->ct_no_masked_label) { > - chassis_features->ct_no_masked_label = false; > - } > - > - bool mac_binding_timestamp = > - smap_get_bool(&chassis->other_config, > - OVN_FEATURE_MAC_BINDING_TIMESTAMP, > - false); > - if (!mac_binding_timestamp && > - chassis_features->mac_binding_timestamp) { > - chassis_features->mac_binding_timestamp = false; > - } > - > - bool ct_lb_related = > - smap_get_bool(&chassis->other_config, > - OVN_FEATURE_CT_LB_RELATED, > - false); > - if (!ct_lb_related && > - chassis_features->ct_lb_related) { > - chassis_features->ct_lb_related = false; > - } > - > - bool fdb_timestamp = > - smap_get_bool(&chassis->other_config, > - OVN_FEATURE_FDB_TIMESTAMP, > - false); > - if (!fdb_timestamp && > - chassis_features->fdb_timestamp) { > - chassis_features->fdb_timestamp = false; > - } > - > - bool ls_dpg_column = > - smap_get_bool(&chassis->other_config, > - OVN_FEATURE_LS_DPG_COLUMN, > - false); > - if (!ls_dpg_column && > - chassis_features->ls_dpg_column) { > - chassis_features->ls_dpg_column = false; > - } > - } > -} > - > static uint32_t > allocate_queueid(unsigned long *queue_id_bitmap) > { > @@ -954,7 +887,7 @@ is_vxlan_mode(const struct sbrec_chassis_table > *sbrec_chassis_table) > return false; > } > > -static uint32_t > +uint32_t > get_ovn_max_dp_key_local(const struct sbrec_chassis_table > *sbrec_chassis_table) > { > if (is_vxlan_mode(sbrec_chassis_table)) { > @@ -3367,6 +3300,8 @@ create_or_get_service_mon(struct ovsdb_idl_txn > *ovnsb_txn, > static void > ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn, > const struct ovn_northd_lb *lb, > + const char *svc_monitor_mac, > + const struct eth_addr *svc_monitor_mac_ea, > struct hmap *monitor_map, struct hmap *ls_ports, > struct sset *svc_monitor_lsps) > { > @@ -3412,7 +3347,7 @@ ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn, > struct eth_addr ea; > if (!mon_info->sbrec_mon->src_mac || > !eth_addr_from_string(mon_info->sbrec_mon->src_mac, &ea) || > - !eth_addr_equals(ea, svc_monitor_mac_ea)) { > + !eth_addr_equals(ea, *svc_monitor_mac_ea)) { > sbrec_service_monitor_set_src_mac(mon_info->sbrec_mon, > svc_monitor_mac); > } > @@ -3624,6 +3559,8 @@ static void > build_lb_svcs( > struct ovsdb_idl_txn *ovnsb_txn, > const struct sbrec_service_monitor_table *sbrec_service_monitor_table, > + const char *svc_monitor_mac, > + const struct eth_addr *svc_monitor_mac_ea, > struct hmap *ls_ports, struct hmap *lb_dps_map, > struct sset *svc_monitor_lsps, > struct hmap *svc_monitor_map) > @@ -3642,7 +3579,8 @@ build_lb_svcs( > > struct ovn_lb_datapaths *lb_dps; > HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) { > - ovn_lb_svc_create(ovnsb_txn, lb_dps->lb, svc_monitor_map, ls_ports, > + ovn_lb_svc_create(ovnsb_txn, lb_dps->lb, svc_monitor_mac, > + svc_monitor_mac_ea, svc_monitor_map, ls_ports, > svc_monitor_lsps); > } > > @@ -3734,13 +3672,16 @@ static void > build_lb_port_related_data( > struct ovsdb_idl_txn *ovnsb_txn, > const struct sbrec_service_monitor_table *sbrec_service_monitor_table, > + const char *svc_monitor_mac, > + const struct eth_addr *svc_monitor_mac_ea, > struct ovn_datapaths *lr_datapaths, struct hmap *ls_ports, > struct hmap *lb_dps_map, struct hmap *lb_group_dps_map, > struct sset *svc_monitor_lsps, > struct hmap *svc_monitor_map) > { > build_lrouter_lbs_check(lr_datapaths); > - build_lb_svcs(ovnsb_txn, sbrec_service_monitor_table, ls_ports, > lb_dps_map, > + build_lb_svcs(ovnsb_txn, sbrec_service_monitor_table, svc_monitor_mac, > + svc_monitor_mac_ea, ls_ports, lb_dps_map, > svc_monitor_lsps, svc_monitor_map); > build_lswitch_lbs_from_lrouter(lr_datapaths, lb_dps_map, > lb_group_dps_map); > } > @@ -9069,6 +9010,7 @@ build_lswitch_arp_nd_responder_default(struct > ovn_datapath *od, > static void > build_lswitch_arp_nd_service_monitor(const struct ovn_lb_datapaths *lb_dps, > const struct hmap *ls_ports, > + const char *svc_monitor_mac, > struct lflow_table *lflows, > struct ds *actions, > struct ds *match) > @@ -15475,6 +15417,7 @@ struct lswitch_flow_build_info { > struct ds match; > struct ds actions; > size_t thread_lflow_counter; > + const char *svc_monitor_mac; > }; > > /* Helper function to combine all lflow generation which is iterated by > @@ -15696,6 +15639,7 @@ build_lflows_thread(void *arg) > } > build_lswitch_arp_nd_service_monitor(lb_dps, > lsi->ls_ports, > + > lsi->svc_monitor_mac, > lsi->lflows, > &lsi->match, > &lsi->actions); > @@ -15816,7 +15760,8 @@ build_lswitch_and_lrouter_flows( > const struct hmap *lb_dps_map, > const struct hmap *svc_monitor_map, > const struct hmap *bfd_connections, > - const struct chassis_features *features) > + const struct chassis_features *features, > + const char *svc_monitor_mac) > { > > char *svc_check_match = xasprintf("eth.dst == %s", svc_monitor_mac); > @@ -15849,6 +15794,7 @@ build_lswitch_and_lrouter_flows( > lsiv[index].features = features; > lsiv[index].svc_check_match = svc_check_match; > lsiv[index].thread_lflow_counter = 0; > + lsiv[index].svc_monitor_mac = svc_monitor_mac; > ds_init(&lsiv[index].match); > ds_init(&lsiv[index].actions); > > @@ -15888,6 +15834,7 @@ build_lswitch_and_lrouter_flows( > .bfd_connections = bfd_connections, > .features = features, > .svc_check_match = svc_check_match, > + .svc_monitor_mac = svc_monitor_mac, > .match = DS_EMPTY_INITIALIZER, > .actions = DS_EMPTY_INITIALIZER, > }; > @@ -15927,6 +15874,7 @@ build_lswitch_and_lrouter_flows( > stopwatch_start(LFLOWS_LBS_STOPWATCH_NAME, time_msec()); > HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) { > build_lswitch_arp_nd_service_monitor(lb_dps, lsi.ls_ports, > + lsi.svc_monitor_mac, > lsi.lflows, &lsi.actions, > &lsi.match); > build_lrouter_defrag_flows_for_lb(lb_dps, lsi.lflows, > @@ -16040,7 +15988,8 @@ void build_lflows(struct ovsdb_idl_txn *ovnsb_txn, > input_data->lb_datapaths_map, > input_data->svc_monitor_map, > input_data->bfd_connections, > - input_data->features); > + input_data->features, > + input_data->svc_monitor_mac); > > if (parallelization_state == STATE_INIT_HASH_SIZES) { > parallelization_state = STATE_USE_PARALLELIZATION; > @@ -16339,6 +16288,7 @@ lflow_handle_northd_lb_changes(struct ovsdb_idl_txn > *ovnsb_txn, > struct ds actions = DS_EMPTY_INITIALIZER; > > build_lswitch_arp_nd_service_monitor(lb_dps, lflow_input->ls_ports, > + lflow_input->svc_monitor_mac, > lflows, &actions, > &match); > build_lrouter_defrag_flows_for_lb(lb_dps, lflows, > @@ -17105,18 +17055,6 @@ destroy_datapaths_and_ports(struct ovn_datapaths > *ls_datapaths, > ovn_datapaths_destroy(lr_datapaths); > } > > -static void > -northd_enable_all_features(struct northd_data *data) > -{ > - data->features = (struct chassis_features) { > - .ct_no_masked_label = true, > - .mac_binding_timestamp = true, > - .ct_lb_related = true, > - .fdb_timestamp = true, > - .ls_dpg_column = true, > - }; > -} > - > void > northd_init(struct northd_data *data) > { > @@ -17127,8 +17065,6 @@ northd_init(struct northd_data *data) > hmap_init(&data->lb_datapaths_map); > hmap_init(&data->lb_group_datapaths_map); > ovs_list_init(&data->lr_list); > - northd_enable_all_features(data); > - data->ovn_internal_version_changed = false; > sset_init(&data->svc_monitor_lsps); > hmap_init(&data->svc_monitor_map); > init_northd_tracked_data(data); > @@ -17168,7 +17104,6 @@ northd_destroy(struct northd_data *data) > destroy_datapaths_and_ports(&data->ls_datapaths, &data->lr_datapaths, > &data->ls_ports, &data->lr_ports, > &data->lr_list); > - destroy_debug_config(); > > sset_destroy(&data->svc_monitor_lsps); > destroy_northd_tracked_data(data); > @@ -17185,83 +17120,22 @@ ovnnb_db_run(struct northd_input *input_data, > } > stopwatch_start(BUILD_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); > > - /* Sync ipsec configuration. > - * Copy nb_cfg from northbound to southbound database. > - * Also set up to update sb_cfg once our southbound transaction commits. > */ > - const struct nbrec_nb_global *nb = nbrec_nb_global_table_first( > - input_data->nbrec_nb_global_table); > - if (!nb) { > - nb = nbrec_nb_global_insert(ovnnb_txn); > - } > - > - const char *mac_addr_prefix = set_mac_prefix(smap_get(&nb->options, > - "mac_prefix")); > - > - const char *monitor_mac = smap_get(&nb->options, "svc_monitor_mac"); > - if (monitor_mac) { > - if (eth_addr_from_string(monitor_mac, &svc_monitor_mac_ea)) { > - snprintf(svc_monitor_mac, sizeof svc_monitor_mac, > - ETH_ADDR_FMT, ETH_ADDR_ARGS(svc_monitor_mac_ea)); > - } else { > - monitor_mac = NULL; > - } > - } > - > - struct smap options; > - smap_clone(&options, &nb->options); > - > - smap_replace(&options, "mac_prefix", mac_addr_prefix); > - > - if (!monitor_mac) { > - eth_addr_random(&svc_monitor_mac_ea); > - snprintf(svc_monitor_mac, sizeof svc_monitor_mac, > - ETH_ADDR_FMT, ETH_ADDR_ARGS(svc_monitor_mac_ea)); > - smap_replace(&options, "svc_monitor_mac", svc_monitor_mac); > - } > - > - char *max_tunid = xasprintf("%d", > - get_ovn_max_dp_key_local(input_data->sbrec_chassis_table)); > - smap_replace(&options, "max_tunid", max_tunid); > - free(max_tunid); > - > - char *ovn_internal_version = ovn_get_internal_version(); > - if (!strcmp(ovn_internal_version, > - smap_get_def(&options, "northd_internal_version", ""))) { > - data->ovn_internal_version_changed = false; > - } else { > - smap_replace(&options, "northd_internal_version", > - ovn_internal_version); > - } > - free(ovn_internal_version); > - > - if (!smap_equal(&nb->options, &options)) { > - nbrec_nb_global_verify_options(nb); > - nbrec_nb_global_set_options(nb, &options); > - } > - > - use_ct_inv_match = smap_get_bool(&nb->options, > + use_ct_inv_match = smap_get_bool(input_data->nb_options, > "use_ct_inv_match", true); > > /* deprecated, use --event instead */ > - controller_event_en = smap_get_bool(&nb->options, > + controller_event_en = smap_get_bool(input_data->nb_options, > "controller_event", false); > - check_lsp_is_up = !smap_get_bool(&nb->options, > + check_lsp_is_up = !smap_get_bool(input_data->nb_options, > "ignore_lsp_down", true); > - default_acl_drop = smap_get_bool(&nb->options, "default_acl_drop", > false); > + default_acl_drop = smap_get_bool(input_data->nb_options, > + "default_acl_drop", false); > > - install_ls_lb_from_router = smap_get_bool(&nb->options, > + install_ls_lb_from_router = smap_get_bool(input_data->nb_options, > "install_ls_lb_from_router", > false); > - use_common_zone = smap_get_bool(&nb->options, "use_common_zone", false); > - > - if (smap_get_bool(&nb->options, "ignore_chassis_features", false)) { > - northd_enable_all_features(data); > - } else { > - build_chassis_features(input_data->sbrec_chassis_table, > - &data->features); > - } > - > - init_debug_config(nb); > + use_common_zone = smap_get_bool(input_data->nb_options, > "use_common_zone", > + false); > > build_datapaths(ovnsb_txn, > input_data->nbrec_logical_switch_table, > @@ -17286,6 +17160,8 @@ ovnnb_db_run(struct northd_input *input_data, > &data->ls_ports, &data->lr_ports); > build_lb_port_related_data(ovnsb_txn, > input_data->sbrec_service_monitor_table, > + input_data->svc_monitor_mac, > + &input_data->svc_monitor_mac_ea, > &data->lr_datapaths, &data->ls_ports, > &data->lb_datapaths_map, > &data->lb_group_datapaths_map, > @@ -17318,38 +17194,6 @@ ovnnb_db_run(struct northd_input *input_data, > &data->ls_datapaths.datapaths); > stopwatch_stop(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); > > - /* Set up SB_Global (depends on chassis features). */ > - const struct sbrec_sb_global *sb = sbrec_sb_global_table_first( > - input_data->sbrec_sb_global_table); > - if (!sb) { > - sb = sbrec_sb_global_insert(ovnsb_txn); > - } > - if (nb->ipsec != sb->ipsec) { > - sbrec_sb_global_set_ipsec(sb, nb->ipsec); > - } > - > - /* Inform ovn-controllers whether LB flows will use ct_mark (i.e., only > - * if all chassis support it). If not explicitly present in the database > - * the default value to be used for this option is 'true'. > - */ > - if (!data->features.ct_no_masked_label) { > - smap_replace(&options, "lb_hairpin_use_ct_mark", "false"); > - } else { > - smap_remove(&options, "lb_hairpin_use_ct_mark"); > - } > - > - /* Hackaround SB_global.options overwrite by NB_Global.options for > - * 'sbctl_probe_interval' option. > - */ > - const char *sip = smap_get(&sb->options, "sbctl_probe_interval"); > - if (sip) { > - smap_replace(&options, "sbctl_probe_interval", sip); > - } > - > - if (!smap_equal(&sb->options, &options)) { > - sbrec_sb_global_set_options(sb, &options); > - } > - smap_destroy(&options); > } > > /* Stores the set of chassis which references an ha_chassis_group. > @@ -17640,12 +17484,6 @@ ovnsb_db_run(struct ovsdb_idl_txn *ovnnb_txn, > ovn_update_ipv6_prefix(lr_ports); > } > > -const char * > -northd_get_svc_monitor_mac(void) > -{ > - return svc_monitor_mac; > -} > - > const struct ovn_datapath * > northd_get_datapath_for_port(const struct hmap *ls_ports, > const char *port_name) > diff --git a/northd/northd.h b/northd/northd.h > index 579edb8bdf..7015402c5f 100644 > --- a/northd/northd.h > +++ b/northd/northd.h > @@ -27,7 +27,6 @@ > > struct northd_input { > /* Northbound table references */ > - const struct nbrec_nb_global_table *nbrec_nb_global_table; > const struct nbrec_logical_switch_table *nbrec_logical_switch_table; > const struct nbrec_logical_router_table *nbrec_logical_router_table; > const struct nbrec_static_mac_binding_table > @@ -37,7 +36,6 @@ struct northd_input { > const struct nbrec_mirror_table *nbrec_mirror_table; > > /* Southbound table references */ > - const struct sbrec_sb_global_table *sbrec_sb_global_table; > const struct sbrec_datapath_binding_table *sbrec_datapath_binding_table; > const struct sbrec_port_binding_table *sbrec_port_binding_table; > const struct sbrec_mac_binding_table *sbrec_mac_binding_table; > @@ -57,6 +55,13 @@ struct northd_input { > const struct hmap *lbs; > const struct hmap *lbgrps; > > + /* Global config data node inputs. */ > + const struct smap *nb_options; > + const struct smap *sb_options; > + const char *svc_monitor_mac; > + struct eth_addr svc_monitor_mac_ea; > + const struct chassis_features *features; > + > /* Indexes */ > struct ovsdb_idl_index *sbrec_chassis_by_name; > struct ovsdb_idl_index *sbrec_chassis_by_hostname; > @@ -66,14 +71,6 @@ struct northd_input { > struct ovsdb_idl_index *sbrec_fdb_by_dp_and_port; > }; > > -struct chassis_features { > - bool ct_no_masked_label; > - bool mac_binding_timestamp; > - bool ct_lb_related; > - bool fdb_timestamp; > - bool ls_dpg_column; > -}; > - > /* A collection of datapaths. E.g. all logical switch datapaths, or all > * logical router datapaths. */ > struct ovn_datapaths { > @@ -156,8 +153,6 @@ struct northd_data { > struct hmap lb_datapaths_map; > struct hmap lb_group_datapaths_map; > struct ovs_list lr_list; > - bool ovn_internal_version_changed; > - struct chassis_features features; > struct sset svc_monitor_lsps; > struct hmap svc_monitor_map; > > @@ -194,6 +189,7 @@ struct lflow_input { > const struct chassis_features *features; > const struct hmap *svc_monitor_map; > bool ovn_internal_version_changed; > + const char *svc_monitor_mac; > }; > > extern int parallelization_state; > @@ -711,8 +707,6 @@ void bfd_cleanup_connections(const struct nbrec_bfd_table > *, > struct hmap *bfd_map); > void run_update_worker_pool(int n_threads); > > -const char *northd_get_svc_monitor_mac(void); > - > const struct ovn_datapath *northd_get_datapath_for_port( > const struct hmap *ls_ports, const char *port_name); > > @@ -770,4 +764,6 @@ bool lrouter_port_ipv4_reachable(const struct ovn_port *, > ovs_be32 addr); > bool lrouter_port_ipv6_reachable(const struct ovn_port *, > const struct in6_addr *); > > +uint32_t get_ovn_max_dp_key_local(const struct sbrec_chassis_table *); > + > #endif /* NORTHD_H */ > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index 5c33a8a6c2..fc9787bc40 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -8782,7 +8782,7 @@ AT_CHECK([grep "ls_in_lb " S1flows | sed > 's/table=../table=??/' | sort], [0], [d > table=??(ls_in_lb ), priority=0 , match=(1), action=(next;) > ]) > > -ovn-nbctl --wait=sb set NB_Global . options:install_ls_lb_from_router=true > +check ovn-nbctl --wait=sb set NB_Global . > options:install_ls_lb_from_router=true > > ovn-sbctl dump-flows S0 > S0flows > ovn-sbctl dump-flows S1 > S1flows > @@ -8801,6 +8801,7 @@ AT_CHECK([grep "ls_in_lb " S1flows | sed > 's/table=../table=??/' | sort], [0], [d > table=??(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == > 172.16.0.11 && tcp.dst == 8080), action=(reg0[[1]] = 0; > ct_lb_mark(backends=10.0.0.2:8080);) > ]) > > + > ovn-sbctl get datapath S0 _uuid > dp_uuids > ovn-sbctl get datapath S1 _uuid >> dp_uuids > lb_dp_group=$(ovn-sbctl --bare --columns ls_datapath_group find > Load_Balancer name=lb0) > @@ -8809,7 +8810,7 @@ AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns > _uuid,datapaths find Logical_DP_Gr > $(cat dp_uuids | sort) > ]) > > -ovn-nbctl --wait=sb set NB_Global . options:install_ls_lb_from_router=false > +check ovn-nbctl --wait=sb set NB_Global . > options:install_ls_lb_from_router=false > > ovn-sbctl dump-flows S0 > S0flows > ovn-sbctl dump-flows S1 > S1flows > @@ -9166,12 +9167,11 @@ $4 > AS_BOX([Create new PG1 and PG2]) > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > check ovn-nbctl --wait=sb -- pg-add pg1 -- pg-add pg2 > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl The port_group node recomputes every time a NB port group is > added/deleted. > @@ -9204,12 +9204,11 @@ check ovn-nbctl --wait=sb \ > check_column "sw1.1" sb:Port_Group ports name="${sw1_key}_pg1" > check_column "sw2.1" sb:Port_Group ports name="${sw2_key}_pg1" > > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl The port_group node recomputes also every time a port from a new switch > @@ -9241,12 +9240,11 @@ check_column "sw2.1" sb:Port_Group ports > name="${sw2_key}_pg1" > check_column "sw1.2" sb:Port_Group ports name="${sw1_key}_pg2" > check_column "sw2.2" sb:Port_Group ports name="${sw2_key}_pg2" > > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl The port_group node recomputes also every time a port from a new switch > @@ -9279,12 +9277,11 @@ check_column "sw2.1 sw2.3" sb:Port_Group ports > name="${sw2_key}_pg1" > check_column "sw1.2 sw1.3" sb:Port_Group ports name="${sw1_key}_pg2" > check_column "sw2.2 sw2.3" sb:Port_Group ports name="${sw2_key}_pg2" > > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl We did not change the set of switches a pg is applied to, there should be > @@ -9322,7 +9319,7 @@ dnl though, therefore "compute: 1". > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl We did not change the set of switches a pg is applied to, there should be > @@ -9354,12 +9351,11 @@ check_column "sw1.2" sb:Port_Group ports > name="${sw1_key}_pg2" > AT_CHECK([fetch_column sb:Port_Group ports name="${sw2_key}_pg2"], [0], [ > ]) > > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl We changed the set of switches a pg is applied to, there should be > @@ -9392,12 +9388,11 @@ check_column "sw1.2" sb:Port_Group ports > name="${sw1_key}_pg2" > AT_CHECK([fetch_column sb:Port_Group ports name="${sw2_key}_pg2"], [0], [ > ]) > > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl We changed the set of switches a pg is applied to, there should be > @@ -9430,12 +9425,11 @@ check_column "sw2.1" sb:Port_Group ports > name="${sw2_key}_pg1" > check_column "sw1.2" sb:Port_Group ports name="${sw1_key}_pg2" > check_column "sw2.2" sb:Port_Group ports name="${sw2_key}_pg2" > > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl We changed the set of switches a pg is applied to, there should be a > @@ -9470,12 +9464,11 @@ check_column "sw1.2" sb:Port_Group ports > name="${sw1_key}_pg2" > AT_CHECK([fetch_column sb:Port_Group ports name="${sw2_key}_pg2"], [0], [ > ]) > > -dnl The northd node should not recompute, it should handle nb_global update > -dnl though, therefore "compute: 1". > +dnl The northd node should not recompute,. > AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], > [0], [dnl > Node: northd > - recompute: 0 > -- compute: 1 > +- compute: 0 > - abort: 0 > ]) > dnl We changed the set of switches a pg is applied to, there should be a > @@ -11837,3 +11830,212 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE > OVN_CLEANUP([hv1]) > AT_CLEANUP > ]) > + > +OVN_FOR_EACH_NORTHD_NO_HV([ > +AT_SETUP([NB_Global and SB_Global incremental processing]) > + > +ovn_start > + > +check_engine_stats() { > + node=$1 > + recompute=$2 > + compute=$3 > + > + echo "__file__:__line__: Checking engine stats for node $node : recompute > - \ > +$recompute : compute - $compute" > + > + node_stat=$(as northd ovn-appctl -t ovn-northd inc-engine/show-stats $node) > + # node_stat will be of this format : > + # - Node: lflow - recompute: 3 - compute: 0 - abort: 0 > + node_recompute_ct=$(echo $node_stat | cut -d '-' -f2 | cut -d ':' -f2) > + node_compute_ct=$(echo $node_stat | cut -d '-' -f3 | cut -d ':' -f2) > + > + if [[ "$recompute" == "norecompute" ]]; then > + # node should not be recomputed > + echo "Expecting $node recompute count - $node_recompute_ct to be 0" > + check test "$node_recompute_ct" -eq "0" > + else > + echo "Expecting $node recompute count - $node_recompute_ct not to be 0" > + check test "$node_recompute_ct" -ne "0" > + fi > + > + if [[ "$compute" == "nocompute" ]]; then > + # node should not be computed > + echo "Expecting $node compute count - $node_compute_ct to be 0" > + check test "$node_compute_ct" -eq "0" > + else > + echo "Expecting $node compute count - $node_compute_ct not to be 0" > + check test "$node_compute_ct" -ne "0" > + fi > +} > + > +check ovn-nbctl ls-add sw0 > +check ovn-nbctl lr-add lr0 > +check ovn-nbctl lsp-add sw0 sw0-p1 -- lsp-set-addresses sw0-p1 > "00:00:20:20:00:03 10.0.0.3" > +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:20:20:12:14 10.0.0.1/24 > +check ovn-nbctl lsp-add sw0 sw0-lr0 > +check ovn-nbctl lsp-set-type sw0-lr0 router > +check ovn-nbctl lsp-set-addresses sw0-lr0 router > +check ovn-nbctl --wait=sb lsp-set-options sw0-lr0 router-port=lr0-sw0 > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > + > +# This should not result in recomputes. > +check ovn-nbctl --wait=sb set NB_Global . options:foo=bar > +check_engine_stats global_config norecompute compute > +check_engine_stats northd norecompute compute > +check_engine_stats lflow norecompute compute > +CHECK_NO_CHANGE_AFTER_RECOMPUTE > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +# This should result in recomputes. > +check ovn-sbctl set SB_Global . options:bar=foo > +check_engine_stats global_config recompute compute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > +CHECK_NO_CHANGE_AFTER_RECOMPUTE > + > +# Clears an nb option and checks that recomputes were triggered > +# and the option was added back by ovn-northd or not depending > +# on the 'added_back' argument. > +clear_nb_option() { > + option=$1 > + add_back=$2 > + echo "clearing the nb option - $option" > + check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > + check ovn-nbctl --wait=sb remove NB_Global . options $option > + check_engine_stats global_config recompute compute > + check_engine_stats northd recompute nocompute > + check_engine_stats lflow recompute nocompute > + > + local retval=1 > + if [ "$add_back" == "true" ]; then > + retval=0 > + fi > + AT_CHECK([ovn-nbctl get NB_Global . options:$option], [$retval], [ignore], > [ignore]) > +} > + > +# Clear svc_monitor_mac and few other options which result in recompute. > +# and ovn-northd should update the nb options back. > +clear_nb_option svc_monitor_mac true > +clear_nb_option max_tunid true > +clear_nb_option mac_prefix true > +clear_nb_option northd_internal_version true > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-nbctl --wait=sb set NB_Global . > options:ignore_chassis_features=true > +check_engine_stats global_config recompute compute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > + > +clear_nb_option ignore_chassis_features false > + > +set_nb_option_lflow_recompute() { > + local option=$1 > + local value=$2 > + check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > + check ovn-nbctl --wait=sb set NB_Global . options:$option=$value > + check_engine_stats global_config norecompute compute > + check_engine_stats northd recompute nocompute > + check_engine_stats lflow recompute nocompute > + check_engine_stats mac_binding_aging recompute nocompute > + CHECK_NO_CHANGE_AFTER_RECOMPUTE > +} > + > +clear_nb_option_lflow_recompute() { > + local option=$1 > + check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > + check ovn-nbctl --wait=sb remove NB_Global . options $option > + check_engine_stats global_config norecompute compute > + check_engine_stats northd recompute nocompute > + check_engine_stats lflow recompute nocompute > + check_engine_stats mac_binding_aging recompute nocompute > + CHECK_NO_CHANGE_AFTER_RECOMPUTE > +} > + > +set_nb_option_lflow_recompute debug_drop_domain_id 1 > +clear_nb_option_lflow_recompute debug_drop_domain_id > + > +set_nb_option_lflow_recompute debug_drop_collector_set 1 > +clear_nb_option_lflow_recompute debug_drop_collector_set > + > +set_nb_option_lflow_recompute mac_binding_removal_limit 100 > +clear_nb_option_lflow_recompute mac_binding_removal_limit > + > +set_nb_option_lflow_recompute fdb_removal_limit 100 > +clear_nb_option_lflow_recompute fdb_removal_limit > + > +set_nb_option_lflow_recompute controller_event true > +clear_nb_option_lflow_recompute controller_event > + > +set_nb_option_lflow_recompute ignore_lsp_down true > +clear_nb_option_lflow_recompute ignore_lsp_down > + > +set_nb_option_lflow_recompute use_ct_inv_match true > +clear_nb_option_lflow_recompute use_ct_inv_match > + > +set_nb_option_lflow_recompute default_acl_drop true > +clear_nb_option_lflow_recompute default_acl_drop > + > +set_nb_option_lflow_recompute use_common_zone true > +clear_nb_option_lflow_recompute use_common_zone > + > +set_nb_option_lflow_recompute install_ls_lb_from_router true > +clear_nb_option_lflow_recompute install_ls_lb_from_router > + > +# Now test changes to chassis for feature changes. > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-sbctl chassis-add ch1 geneve 127.0.0.1 > +check ovn-nbctl --wait=sb sync > +check_engine_stats global_config recompute compute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-sbctl chassis-add ch2 geneve 127.0.0.2 > +check ovn-nbctl --wait=sb sync > +check_engine_stats global_config recompute compute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > + > +AT_CHECK([ovn-nbctl get NB_Global . options:max_tunid | \ > +sed s/":"//g | sed s/\"//g], [0], [16711680 > +], []) > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-sbctl chassis-del ch2 > +check ovn-nbctl --wait=sb sync > +check_engine_stats global_config recompute compute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-sbctl set encap . type=vxlan > +check ovn-nbctl --wait=sb sync > +check_engine_stats global_config recompute compute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > + > +AT_CHECK([ovn-nbctl get NB_Global . options:max_tunid | \ > +sed s/":"//g | sed s/\"//g], [0], [4095 > +], []) > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-sbctl set chassis . other_config:foo=bar > +check ovn-nbctl --wait=sb sync > +check_engine_stats global_config norecompute compute > +check_engine_stats mac_binding_aging recompute nocompute > +check_engine_stats fdb_aging recompute nocompute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-sbctl set chassis . other_config:ct-no-masked-label=true > +check ovn-nbctl --wait=sb sync > +check_engine_stats global_config norecompute compute > +check_engine_stats mac_binding_aging recompute nocompute > +check_engine_stats fdb_aging recompute nocompute > +check_engine_stats northd recompute nocompute > +check_engine_stats lflow recompute nocompute > + > +AT_CLEANUP > +]) _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev