From patchwork Tue Oct 24 00:50:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1854092 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SDtnQ3Ltlz202k for ; Tue, 24 Oct 2023 11:52:26 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 4A58141983; Tue, 24 Oct 2023 00:52:24 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 4A58141983 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mj9ZEyQVT3eP; Tue, 24 Oct 2023 00:52:20 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id 2AE3941960; Tue, 24 Oct 2023 00:52:19 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 2AE3941960 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id CDAE7C0DD2; Tue, 24 Oct 2023 00:52:18 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id B8CC2C0071 for ; Tue, 24 Oct 2023 00:52:17 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id D9B2741DF4 for ; Tue, 24 Oct 2023 00:50:47 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org D9B2741DF4 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Z8qap1y2T7lq for ; Tue, 24 Oct 2023 00:50:38 +0000 (UTC) Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by smtp4.osuosl.org (Postfix) with ESMTPS id 861B041822 for ; Tue, 24 Oct 2023 00:50:31 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 861B041822 Received: by mail.gandi.net (Postfix) with ESMTPSA id B30EDFF803; Tue, 24 Oct 2023 00:50:28 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Mon, 23 Oct 2023 20:50:16 -0400 Message-ID: <20231024005016.4134060-1-numans@ovn.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231024004244.4133452-1-numans@ovn.org> References: <20231024004244.4133452-1-numans@ovn.org> MIME-Version: 1.0 X-GND-Sasl: numans@ovn.org Subject: [ovs-dev] [PATCH ovn v1 16/18] northd: Add I-P for NB_Global and SB_Global. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Numan Siddique 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 --- 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 | 22 +- northd/inc-proc-northd.c | 38 ++- northd/northd.c | 230 +++------------ northd/northd.h | 24 +- tests/ovn-northd.at | 256 +++++++++++++++-- 12 files changed, 1014 insertions(+), 297 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 f626c72c8c..cf988b39c4 100644 --- a/northd/aging.c +++ b/northd/aging.c @@ -15,6 +15,7 @@ #include +#include "en-global-config.h" #include "lib/inc-proc-eng.h" #include "lib/ovn-nb-idl.h" #include "lib/ovn-sb-idl.h" @@ -100,15 +101,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 */ @@ -142,11 +138,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; } @@ -271,9 +270,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 9707be7d8e..482270f5dd 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 + +#include +#include +#include + +/* 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); + + 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; + } + + const struct engine_context *eng_ctx = engine_get_context(); + if (!eng_ctx->ovnsb_idl_txn) { + return false; + } + + 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)) { + 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 + +/* 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 90ebb97657..222665006b 100644 --- a/northd/en-lflow.c +++ b/northd/en-lflow.c @@ -22,6 +22,7 @@ #include "en-lr-nat.h" #include "en-lr-lb-nat-data.h" #include "en-ls-lb-acls.h" +#include "en-global-config.h" #include "en-northd.h" #include "en-meters.h" #include "lflow-mgr.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; + 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 13e731cad9..d4338c6a45 100644 --- a/northd/en-northd.c +++ b/northd/en-northd.c @@ -19,6 +19,7 @@ #include #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 @@ -243,6 +223,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 7c22949f74..7a5d2f0ccd 100644 --- a/northd/en-sync-sb.c +++ b/northd/en-sync-sb.c @@ -23,6 +23,7 @@ #include "en-lr-nat.h" #include "en-lr-lb-nat-data.h" +#include "en-global-config.h" #include "en-sync-sb.h" #include "lib/inc-proc-eng.h" #include "lib/lb.h" @@ -42,7 +43,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_lb_nat_data_table *); + const struct lr_lb_nat_data_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 *, @@ -90,9 +92,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_lb_nat_data *lr_lb_nat_data = engine_get_input_data("lr_lb_nat_data", 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_lb_nat_data->lr_lbnats); + &lr_lb_nat_data->lr_lbnats, + global_config->svc_monitor_mac); engine_set_node_state(node, EN_UPDATED); } @@ -218,12 +223,14 @@ en_sync_to_sb_lb_run(struct engine_node *node, void *data OVS_UNUSED) { const struct sbrec_load_balancer_table *sb_load_balancer_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); const struct engine_context *eng_ctx = engine_get_context(); struct northd_data *northd_data = engine_get_input_data("northd", node); sync_lbs(eng_ctx->ovnsb_idl_txn, sb_load_balancer_table, &northd_data->ls_datapaths, &northd_data->lr_datapaths, - &northd_data->lb_datapaths_map, &northd_data->features); + &northd_data->lb_datapaths_map, &global_config->features); engine_set_node_state(node, EN_UPDATED); } @@ -370,7 +377,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_lb_nat_data_table *lr_lbnats) + const struct lr_lb_nat_data_table *lr_lbnats, + const char *svc_monitor_macp) { struct shash sb_address_sets = SHASH_INITIALIZER(&sb_address_sets); @@ -381,8 +389,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, + }; 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 5c3d9faafa..99ac1079ec 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-lb-nat-data.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_lb_nat_data, "lr_lb_nat_data"); @@ -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); @@ -185,11 +193,11 @@ 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); 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, @@ -214,15 +222,17 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, engine_add_input(&en_ls_lbacls, &en_nb_logical_switch, ls_lbacls_logical_switch_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); @@ -236,19 +246,23 @@ 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_lb_nat_data, lflow_lr_lb_nat_data_handler); engine_add_input(&en_lflow, &en_ls_lbacls, lflow_ls_lbacls_handler); + engine_add_input(&en_sync_to_sb_addr_set, &en_northd, NULL); + engine_add_input(&en_sync_to_sb_addr_set, &en_lr_lb_nat_data, 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_lb_nat_data, 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); @@ -258,6 +272,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, @@ -362,11 +378,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 1f87102a05..b6e24f94d8 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -43,6 +43,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-lb-nat-data.h" @@ -77,14 +78,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; @@ -295,66 +288,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) { @@ -946,7 +879,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)) { @@ -3362,6 +3295,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) { @@ -3407,7 +3342,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); } @@ -3732,6 +3667,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) @@ -3750,7 +3687,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); } @@ -3842,13 +3780,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); } @@ -9373,6 +9314,7 @@ build_lswitch_arp_nd_responder_default(struct ovn_datapath *od, static void build_lswitch_arp_nd_service_monitor(const struct ovn_northd_lb *lb, const struct hmap *ls_ports, + const char *svc_monitor_mac, struct lflow_table *lflows, struct ds *actions, struct ds *match, @@ -15776,6 +15718,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 @@ -16003,6 +15946,7 @@ build_lflows_thread(void *arg) } build_lswitch_arp_nd_service_monitor(lb_dps->lb, lsi->ls_ports, + lsi->svc_monitor_mac, lsi->lflows, &lsi->match, &lsi->actions, @@ -16125,7 +16069,8 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths, 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); @@ -16158,6 +16103,7 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths, 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); @@ -16197,6 +16143,7 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths, .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, }; @@ -16238,6 +16185,7 @@ build_lswitch_and_lrouter_flows(const struct ovn_datapaths *ls_datapaths, 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->lb, lsi.ls_ports, + lsi.svc_monitor_mac, lsi.lflows, &lsi.actions, &lsi.match, lb_dps->lflow_ref); @@ -16356,7 +16304,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; @@ -16597,6 +16546,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->lb, lflow_input->ls_ports, + lflow_input->svc_monitor_mac, lflows, &actions, &match, lb_dps->lflow_ref); build_lrouter_defrag_flows_for_lb(lb_dps, lflows, @@ -17364,18 +17314,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) { @@ -17386,8 +17324,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); data->change_tracked = false; @@ -17428,7 +17364,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); @@ -17445,83 +17380,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, @@ -17546,6 +17420,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, @@ -17578,38 +17454,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. @@ -17900,12 +17744,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 3008c7855f..d1f9d95ee7 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 { @@ -189,8 +186,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; /* Indicates if northd engine node has changes tracked or not. */ @@ -227,6 +222,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; @@ -748,8 +744,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); void sync_lbs(struct ovsdb_idl_txn *, const struct sbrec_load_balancer_table *, @@ -782,4 +776,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 e083c8925f..ba30f4b84c 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -8698,7 +8698,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 @@ -8717,6 +8717,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) @@ -8725,7 +8726,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 @@ -9083,12 +9084,11 @@ $4 AS_BOX([Create new PG1 and PG2]) check as northd ovn-appctl -t NORTHD_TYPE 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 NORTHD_TYPE 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. @@ -9121,12 +9121,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 NORTHD_TYPE 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 @@ -9158,12 +9157,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 NORTHD_TYPE 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 @@ -9196,12 +9194,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 NORTHD_TYPE 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 @@ -9239,7 +9236,7 @@ dnl though, therefore "compute: 1". AT_CHECK([as northd ovn-appctl -t NORTHD_TYPE 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 @@ -9271,12 +9268,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 NORTHD_TYPE 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 @@ -9309,12 +9305,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 NORTHD_TYPE 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 @@ -9347,12 +9342,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 NORTHD_TYPE 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 @@ -9387,12 +9381,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 NORTHD_TYPE 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 @@ -11307,3 +11300,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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 NORTHD_TYPE 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 +])