This new engine now maintains the gateway related data for ovn-ic daemon which was earlier maintained by the ic engine node invoked the gateway_run() function. The inputs to this engine node are: en_icsb_gateway; en_sb_chassis;
In order to achieve this, we refactor in the following way: * Introduce gateway_init() which initializes this data. * Introduce gateway_destroy() which clears this data for a new iteration. * Introduce gateway_run() which invokes the full recompute of the engine. This engine node becomes an input to 'ic' node. Signed-off-by: Paulo Guilherme Silva <[email protected]> --- ic/automake.mk | 2 + ic/en-gateway.c | 268 ++++++++++++++++++++++++++++++++++++++++++ ic/en-gateway.h | 28 +++++ ic/en-ic.c | 2 - ic/inc-proc-ic.c | 7 +- ic/ovn-ic.c | 149 +---------------------- ic/ovn-ic.h | 1 - lib/stopwatch-names.h | 1 + 8 files changed, 306 insertions(+), 152 deletions(-) create mode 100644 ic/en-gateway.c create mode 100644 ic/en-gateway.h diff --git a/ic/automake.mk b/ic/automake.mk index 24807a360..1fca1eb38 100644 --- a/ic/automake.mk +++ b/ic/automake.mk @@ -4,6 +4,8 @@ ic_ovn_ic_SOURCES = ic/ovn-ic.c \ ic/ovn-ic.h \ ic/en-ic.c \ ic/en-ic.h \ + ic/en-gateway.c \ + ic/en-gateway.h \ ic/en-enum-datapaths.c \ ic/en-enum-datapaths.h \ ic/en-port-binding.c \ diff --git a/ic/en-gateway.c b/ic/en-gateway.c new file mode 100644 index 000000000..d0eb77564 --- /dev/null +++ b/ic/en-gateway.c @@ -0,0 +1,268 @@ +/* + * 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 "ovn-ic.h" +#include "en-gateway.h" +#include "inc-proc-ic.h" +#include "lib/inc-proc-eng.h" +#include "lib/ovn-sb-idl.h" +#include "lib/ovn-ic-sb-idl.h" +#include "lib/ovn-util.h" +#include "lib/stopwatch-names.h" +#include "coverage.h" +#include "stopwatch.h" +#include "stopwatch-names.h" + +VLOG_DEFINE_THIS_MODULE(gateway); +COVERAGE_DEFINE(gateway_run); + +static void +gateway_run(const struct engine_context *eng_ctx, + struct gateway_input *gateway_input, + struct ed_type_gateway *gateway_data, + const struct icsbrec_gateway_table *icsb_gateway_table, + const struct sbrec_chassis_table *sb_chassis_table); +static void gateway_init(struct ed_type_gateway *data); +static void gateway_destroy(struct ed_type_gateway *data); +static void gateway_clear(struct ed_type_gateway *data); +static void +sync_sb_gw_to_isb(const struct engine_context *ctx, + const struct sbrec_chassis *chassis, + const struct icsbrec_gateway *gw); +static void +sync_isb_gw_to_sb(const struct engine_context *ctx, + const struct icsbrec_gateway *gw, + const struct sbrec_chassis *chassis); +static bool +is_gateway_data_changed(const struct icsbrec_gateway *gw, + const struct sbrec_chassis *chassis); + +enum engine_node_state +en_gateway_run(struct engine_node *node, void *data) +{ + const struct engine_context *eng_ctx = engine_get_context(); + struct ed_type_gateway *gateway_data = data; + struct gateway_input gateway_input; + + gateway_clear(gateway_data); + + const struct icsbrec_gateway_table *icsb_gateway_table = + EN_OVSDB_GET(engine_get_input("ICSB_gateway", node)); + const struct sbrec_chassis_table *sb_chassis_table = + EN_OVSDB_GET(engine_get_input("SB_chassis", node)); + + gateway_input.runned_az = eng_ctx->client_ctx; + + COVERAGE_INC(gateway_run); + stopwatch_start(OVN_IC_GATEWAY_RUN_STOPWATCH_NAME, time_usec()); + gateway_run(eng_ctx, &gateway_input, gateway_data, icsb_gateway_table, + sb_chassis_table); + stopwatch_stop(OVN_IC_GATEWAY_RUN_STOPWATCH_NAME, time_usec()); + + return EN_UPDATED; +} + +void * +en_gateway_init(struct engine_node *node OVS_UNUSED, + struct engine_arg *arg OVS_UNUSED) +{ + struct ed_type_gateway *data = xzalloc(sizeof *data); + gateway_init(data); + return data; +} + +void +en_gateway_cleanup(void *data) +{ + gateway_destroy(data); +} + +static void +gateway_init(struct ed_type_gateway *data) +{ + shash_init(&data->local_gws); + shash_init(&data->remote_gws); +} + +static void +gateway_destroy(struct ed_type_gateway *data) +{ + gateway_clear(data); + + shash_destroy(&data->local_gws); + shash_destroy(&data->remote_gws); +} + +static void +gateway_clear(struct ed_type_gateway *data) +{ + shash_clear(&data->local_gws); + shash_clear(&data->remote_gws); +} + +static void +gateway_run(const struct engine_context *eng_ctx, + struct gateway_input *gw_input, + struct ed_type_gateway *gw_data, + const struct icsbrec_gateway_table *icsb_gateway_table, + const struct sbrec_chassis_table *sb_chassis_table) +{ + if (!eng_ctx->ovnisb_idl_txn || !eng_ctx->ovnsb_idl_txn) { + return; + } + + const struct icsbrec_gateway *gw; + ICSBREC_GATEWAY_TABLE_FOR_EACH (gw, icsb_gateway_table) { + if (gw->availability_zone == gw_input->runned_az) { + shash_add(&gw_data->local_gws, gw->name, gw); + } else { + shash_add(&gw_data->remote_gws, gw->name, gw); + } + } + + const struct sbrec_chassis *chassis; + SBREC_CHASSIS_TABLE_FOR_EACH (chassis, sb_chassis_table) { + if (smap_get_bool(&chassis->other_config, "is-interconn", false)) { + gw = shash_find_and_delete(&gw_data->local_gws, chassis->name); + if (!gw) { + gw = icsbrec_gateway_insert(eng_ctx->ovnisb_idl_txn); + icsbrec_gateway_set_availability_zone(gw, gw_input->runned_az); + icsbrec_gateway_set_name(gw, chassis->name); + sync_sb_gw_to_isb(eng_ctx, chassis, gw); + } else if (is_gateway_data_changed(gw, chassis)) { + sync_sb_gw_to_isb(eng_ctx, chassis, gw); + } + } else if (smap_get_bool(&chassis->other_config, "is-remote", false)) { + gw = shash_find_and_delete(&gw_data->remote_gws, chassis->name); + if (!gw) { + sbrec_chassis_delete(chassis); + } else if (is_gateway_data_changed(gw, chassis)) { + sync_isb_gw_to_sb(eng_ctx, gw, chassis); + } + } + } + + /* Delete extra gateways from ISB for the local AZ */ + struct shash_node *node; + SHASH_FOR_EACH (node, &gw_data->local_gws) { + icsbrec_gateway_delete(node->data); + } + + /* Create SB chassis for remote gateways in ISB */ + SHASH_FOR_EACH (node, &gw_data->remote_gws) { + gw = node->data; + chassis = sbrec_chassis_insert(eng_ctx->ovnsb_idl_txn); + sbrec_chassis_set_name(chassis, gw->name); + sync_isb_gw_to_sb(eng_ctx, gw, chassis); + } +} + +/* Returns true if any information in gw and chassis is different. */ +static bool +is_gateway_data_changed(const struct icsbrec_gateway *gw, + const struct sbrec_chassis *chassis) +{ + if (strcmp(gw->hostname, chassis->hostname)) { + return true; + } + + if (gw->n_encaps != chassis->n_encaps) { + return true; + } + + for (int g = 0; g < gw->n_encaps; g++) { + + bool found = false; + const struct icsbrec_encap *gw_encap = gw->encaps[g]; + for (int s = 0; s < chassis->n_encaps; s++) { + const struct sbrec_encap *chassis_encap = chassis->encaps[s]; + if (!strcmp(gw_encap->type, chassis_encap->type) && + !strcmp(gw_encap->ip, chassis_encap->ip)) { + found = true; + if (!smap_equal(&gw_encap->options, &chassis_encap->options)) { + return true; + } + break; + } + } + if (!found) { + return true; + } + } + + return false; +} + +static void +sync_isb_gw_to_sb(const struct engine_context *ctx, + const struct icsbrec_gateway *gw, + const struct sbrec_chassis *chassis) +{ + sbrec_chassis_set_hostname(chassis, gw->hostname); + sbrec_chassis_update_other_config_setkey(chassis, "is-remote", "true"); + + /* Sync encaps used by this gateway. */ + ovs_assert(gw->n_encaps); + struct sbrec_encap *sb_encap; + struct sbrec_encap **sb_encaps = + xmalloc(gw->n_encaps * sizeof *sb_encaps); + for (int i = 0; i < gw->n_encaps; i++) { + sb_encap = sbrec_encap_insert(ctx->ovnsb_idl_txn); + sbrec_encap_set_chassis_name(sb_encap, gw->name); + sbrec_encap_set_ip(sb_encap, gw->encaps[i]->ip); + sbrec_encap_set_type(sb_encap, gw->encaps[i]->type); + sbrec_encap_set_options(sb_encap, &gw->encaps[i]->options); + sb_encaps[i] = sb_encap; + } + sbrec_chassis_set_encaps(chassis, sb_encaps, gw->n_encaps); + free(sb_encaps); +} + +static void +sync_sb_gw_to_isb(const struct engine_context *ctx, + const struct sbrec_chassis *chassis, + const struct icsbrec_gateway *gw) +{ + icsbrec_gateway_set_hostname(gw, chassis->hostname); + + /* Sync encaps used by this chassis. */ + ovs_assert(chassis->n_encaps); + struct icsbrec_encap *isb_encap; + struct icsbrec_encap **isb_encaps = + xmalloc(chassis->n_encaps * sizeof *isb_encaps); + for (int i = 0; i < chassis->n_encaps; i++) { + isb_encap = icsbrec_encap_insert(ctx->ovnisb_idl_txn); + icsbrec_encap_set_gateway_name(isb_encap, + chassis->name); + icsbrec_encap_set_ip(isb_encap, chassis->encaps[i]->ip); + icsbrec_encap_set_type(isb_encap, + chassis->encaps[i]->type); + icsbrec_encap_set_options(isb_encap, + &chassis->encaps[i]->options); + isb_encaps[i] = isb_encap; + } + icsbrec_gateway_set_encaps(gw, isb_encaps, + chassis->n_encaps); + free(isb_encaps); +} diff --git a/ic/en-gateway.h b/ic/en-gateway.h new file mode 100644 index 000000000..9010d27f4 --- /dev/null +++ b/ic/en-gateway.h @@ -0,0 +1,28 @@ +#ifndef EN_IC_GATEWAY_H +#define EN_IC_GATEWAY_H 1 + +#include <config.h> + +#include <stdbool.h> +#include <getopt.h> +#include <stdlib.h> +#include <stdio.h> + +/* OVN includes. */ +#include "lib/inc-proc-eng.h" + +struct ed_type_gateway { + struct shash local_gws; + struct shash remote_gws; +}; + +struct gateway_input { + /* Indexes */ + const struct icsbrec_availability_zone *runned_az; +}; + +void *en_gateway_init(struct engine_node *, struct engine_arg *); +enum engine_node_state en_gateway_run(struct engine_node *, void *data); +void en_gateway_cleanup(void *data); + +#endif diff --git a/ic/en-ic.c b/ic/en-ic.c index e0956bdee..af240c20a 100644 --- a/ic/en-ic.c +++ b/ic/en-ic.c @@ -64,8 +64,6 @@ ic_get_input_data(struct engine_node *node, EN_OVSDB_GET(engine_get_input("ICSB_availability_zone", node)); input_data->icsbrec_encap_table = EN_OVSDB_GET(engine_get_input("ICSB_encap", node)); - input_data->icsbrec_gateway_table = - EN_OVSDB_GET(engine_get_input("ICSB_gateway", node)); input_data->icsbrec_datapath_binding_table = EN_OVSDB_GET(engine_get_input("ICSB_datapath_binding", node)); diff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c index 7399dbd57..dc625d759 100644 --- a/ic/inc-proc-ic.c +++ b/ic/inc-proc-ic.c @@ -27,6 +27,7 @@ #include "openvswitch/vlog.h" #include "inc-proc-ic.h" #include "en-ic.h" +#include "en-gateway.h" #include "en-enum-datapaths.h" #include "en-port-binding.h" #include "en-route.h" @@ -161,6 +162,7 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic); /* Define engine nodes for other nodes. They should be defined as static to * avoid sparse errors. */ static ENGINE_NODE(ic, SB_WRITE); +static ENGINE_NODE(gateway, SB_WRITE); static ENGINE_NODE(enum_datapaths); static ENGINE_NODE(port_binding, SB_WRITE); static ENGINE_NODE(route); @@ -172,6 +174,9 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb, { /* Define relationships between nodes where first argument is dependent * on the second argument */ + engine_add_input(&en_gateway, &en_icsb_gateway, NULL); + engine_add_input(&en_gateway, &en_sb_chassis, NULL); + engine_add_input(&en_enum_datapaths, &en_icnb_transit_switch, NULL); engine_add_input(&en_enum_datapaths, &en_icsb_datapath_binding, NULL); @@ -191,6 +196,7 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb, engine_add_input(&en_route, &en_icsb_route, NULL); engine_add_input(&en_route, &en_nb_logical_router_static_route, NULL); + engine_add_input(&en_ic, &en_gateway, NULL); engine_add_input(&en_ic, &en_enum_datapaths, NULL); engine_add_input(&en_ic, &en_port_binding, NULL); engine_add_input(&en_ic, &en_route, NULL); @@ -219,7 +225,6 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb, engine_add_input(&en_ic, &en_icsb_availability_zone, NULL); engine_add_input(&en_ic, &en_icsb_encap, NULL); engine_add_input(&en_ic, &en_icsb_service_monitor, NULL); - engine_add_input(&en_ic, &en_icsb_gateway, NULL); engine_add_input(&en_ic, &en_icsb_datapath_binding, NULL); struct engine_arg engine_arg = { diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index c880244e2..ffd814846 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -429,153 +429,6 @@ tr_run(struct engine_context *ctx, } } -/* Returns true if any information in gw and chassis is different. */ -static bool -is_gateway_data_changed(const struct icsbrec_gateway *gw, - const struct sbrec_chassis *chassis) -{ - if (strcmp(gw->hostname, chassis->hostname)) { - return true; - } - - if (gw->n_encaps != chassis->n_encaps) { - return true; - } - - for (int g = 0; g < gw->n_encaps; g++) { - - bool found = false; - const struct icsbrec_encap *gw_encap = gw->encaps[g]; - for (int s = 0; s < chassis->n_encaps; s++) { - const struct sbrec_encap *chassis_encap = chassis->encaps[s]; - if (!strcmp(gw_encap->type, chassis_encap->type) && - !strcmp(gw_encap->ip, chassis_encap->ip)) { - found = true; - if (!smap_equal(&gw_encap->options, &chassis_encap->options)) { - return true; - } - break; - } - } - if (!found) { - return true; - } - } - - return false; -} - -static void -sync_isb_gw_to_sb(struct engine_context *ctx, - const struct icsbrec_gateway *gw, - const struct sbrec_chassis *chassis) -{ - sbrec_chassis_set_hostname(chassis, gw->hostname); - sbrec_chassis_update_other_config_setkey(chassis, "is-remote", "true"); - - /* Sync encaps used by this gateway. */ - ovs_assert(gw->n_encaps); - struct sbrec_encap *sb_encap; - struct sbrec_encap **sb_encaps = - xmalloc(gw->n_encaps * sizeof *sb_encaps); - for (int i = 0; i < gw->n_encaps; i++) { - sb_encap = sbrec_encap_insert(ctx->ovnsb_idl_txn); - sbrec_encap_set_chassis_name(sb_encap, gw->name); - sbrec_encap_set_ip(sb_encap, gw->encaps[i]->ip); - sbrec_encap_set_type(sb_encap, gw->encaps[i]->type); - sbrec_encap_set_options(sb_encap, &gw->encaps[i]->options); - sb_encaps[i] = sb_encap; - } - sbrec_chassis_set_encaps(chassis, sb_encaps, gw->n_encaps); - free(sb_encaps); -} - -static void -sync_sb_gw_to_isb(struct engine_context *ctx, - const struct sbrec_chassis *chassis, - const struct icsbrec_gateway *gw) -{ - icsbrec_gateway_set_hostname(gw, chassis->hostname); - - /* Sync encaps used by this chassis. */ - ovs_assert(chassis->n_encaps); - struct icsbrec_encap *isb_encap; - struct icsbrec_encap **isb_encaps = - xmalloc(chassis->n_encaps * sizeof *isb_encaps); - for (int i = 0; i < chassis->n_encaps; i++) { - isb_encap = icsbrec_encap_insert(ctx->ovnisb_idl_txn); - icsbrec_encap_set_gateway_name(isb_encap, - chassis->name); - icsbrec_encap_set_ip(isb_encap, chassis->encaps[i]->ip); - icsbrec_encap_set_type(isb_encap, - chassis->encaps[i]->type); - icsbrec_encap_set_options(isb_encap, - &chassis->encaps[i]->options); - isb_encaps[i] = isb_encap; - } - icsbrec_gateway_set_encaps(gw, isb_encaps, - chassis->n_encaps); - free(isb_encaps); -} - -static void -gateway_run(struct engine_context *ctx, - struct ic_input *ic) -{ - if (!ctx->ovnisb_idl_txn || !ctx->ovnsb_idl_txn) { - return; - } - - struct shash local_gws = SHASH_INITIALIZER(&local_gws); - struct shash remote_gws = SHASH_INITIALIZER(&remote_gws); - const struct icsbrec_gateway *gw; - ICSBREC_GATEWAY_TABLE_FOR_EACH (gw, ic->icsbrec_gateway_table) { - if (gw->availability_zone == ic->runned_az) { - shash_add(&local_gws, gw->name, gw); - } else { - shash_add(&remote_gws, gw->name, gw); - } - } - - const struct sbrec_chassis *chassis; - SBREC_CHASSIS_TABLE_FOR_EACH (chassis, ic->sbrec_chassis_table) { - if (smap_get_bool(&chassis->other_config, "is-interconn", false)) { - gw = shash_find_and_delete(&local_gws, chassis->name); - if (!gw) { - gw = icsbrec_gateway_insert(ctx->ovnisb_idl_txn); - icsbrec_gateway_set_availability_zone(gw, ic->runned_az); - icsbrec_gateway_set_name(gw, chassis->name); - sync_sb_gw_to_isb(ctx, chassis, gw); - } else if (is_gateway_data_changed(gw, chassis)) { - sync_sb_gw_to_isb(ctx, chassis, gw); - } - } else if (smap_get_bool(&chassis->other_config, "is-remote", false)) { - gw = shash_find_and_delete(&remote_gws, chassis->name); - if (!gw) { - sbrec_chassis_delete(chassis); - } else if (is_gateway_data_changed(gw, chassis)) { - sync_isb_gw_to_sb(ctx, gw, chassis); - } - } - } - - /* Delete extra gateways from ISB for the local AZ */ - struct shash_node *node; - SHASH_FOR_EACH (node, &local_gws) { - icsbrec_gateway_delete(node->data); - } - shash_destroy(&local_gws); - - /* Create SB chassis for remote gateways in ISB */ - SHASH_FOR_EACH (node, &remote_gws) { - gw = node->data; - chassis = sbrec_chassis_insert(ctx->ovnsb_idl_txn); - sbrec_chassis_set_name(chassis, gw->name); - sync_isb_gw_to_sb(ctx, gw, chassis); - } - shash_destroy(&remote_gws); -} - const struct nbrec_logical_router_port * get_lrp_by_lrp_name(struct ovsdb_idl_index *nbrec_lrp_by_name, const char *lrp_name) @@ -1192,7 +1045,6 @@ ovn_db_run(struct ic_input *input_data, struct ic_data *ic_data, struct engine_context *eng_ctx) { - gateway_run(eng_ctx, input_data); ts_run(eng_ctx, input_data, ic_data->dp_tnlids, ic_data->isb_ts_dps); tr_run(eng_ctx, input_data, ic_data->dp_tnlids, ic_data->isb_tr_dps); sync_service_monitor(eng_ctx, input_data); @@ -1601,6 +1453,7 @@ main(int argc, char *argv[]) stopwatch_create(OVN_IC_ENUM_DATAPATHS_RUN_STOPWATCH_NAME, SW_MS); stopwatch_create(OVN_IC_PORT_BINDING_RUN_STOPWATCH_NAME, SW_MS); stopwatch_create(OVN_IC_ROUTE_RUN_STOPWATCH_NAME, SW_MS); + stopwatch_create(OVN_IC_GATEWAY_RUN_STOPWATCH_NAME, SW_MS); /* Initialize incremental processing engine for ovn-northd */ inc_proc_ic_init(&ovnnb_idl_loop, &ovnsb_idl_loop, diff --git a/ic/ovn-ic.h b/ic/ovn-ic.h index bc4a1e6e0..e6918c8d2 100644 --- a/ic/ovn-ic.h +++ b/ic/ovn-ic.h @@ -34,7 +34,6 @@ struct ic_input { /* InterconnectSouthbound table references */ const struct icsbrec_encap_table *icsbrec_encap_table; - const struct icsbrec_gateway_table *icsbrec_gateway_table; const struct icsbrec_ic_sb_global_table *icsbrec_ic_sb_global_table; const struct icsbrec_datapath_binding_table *icsbrec_datapath_binding_table; diff --git a/lib/stopwatch-names.h b/lib/stopwatch-names.h index c277d4056..cd75376d9 100644 --- a/lib/stopwatch-names.h +++ b/lib/stopwatch-names.h @@ -42,6 +42,7 @@ #define OVN_IC_LOOP_STOPWATCH_NAME "ovn-ic-loop" #define IC_OVN_DB_RUN_STOPWATCH_NAME "ovn_db_run" +#define OVN_IC_GATEWAY_RUN_STOPWATCH_NAME "gateway_run" #define OVN_IC_ENUM_DATAPATHS_RUN_STOPWATCH_NAME "enum_datapaths_run" #define OVN_IC_PORT_BINDING_RUN_STOPWATCH_NAME "port_binding_run" #define OVN_IC_ROUTE_RUN_STOPWATCH_NAME "route_run" -- 2.34.1 -- _'Esta mensagem é direcionada apenas para os endereços constantes no cabeçalho inicial. Se você não está listado nos endereços constantes no cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão imediatamente anuladas e proibidas'._ * **'Apesar do Magazine Luiza tomar todas as precauções razoáveis para assegurar que nenhum vírus esteja presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.* _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
