Propagate the contents of the NB table to the Southbound. Signed-off-by: Dumitru Ceara <dce...@redhat.com> --- Note: - ovn-trace doesn't support template variables (yet).
V2: - Fixed TEMPLATE_VAR_TABLE_INITIALIZER definition so that GCC doesn't complain anymore. - Addressed Han's comments: - Rename tables to Chassis_Template_Var. - Fix man page. - Simplify function prototypes. - Changed schema as suggested by Ilya. --- northd/automake.mk | 4 ++ northd/en-northd.c | 4 ++ northd/inc-proc-northd.c | 8 ++++- northd/northd.c | 41 +++++++++++++++++++++++++ northd/northd.h | 4 ++ northd/template-var.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ northd/template-var.h | 58 ++++++++++++++++++++++++++++++++++++ ovn-nb.ovsschema | 17 +++++++++-- ovn-nb.xml | 29 ++++++++++++++++++ ovn-sb.ovsschema | 12 ++++++- ovn-sb.xml | 15 +++++++++ tests/ovn-northd.at | 35 ++++++++++++++++++++++ utilities/ovn-nbctl.c | 3 ++ utilities/ovn-sbctl.c | 3 ++ 14 files changed, 299 insertions(+), 8 deletions(-) create mode 100644 northd/template-var.c create mode 100644 northd/template-var.h diff --git a/northd/automake.mk b/northd/automake.mk index 81582867dc..31134bc329 100644 --- a/northd/automake.mk +++ b/northd/automake.mk @@ -13,7 +13,9 @@ northd_ovn_northd_SOURCES = \ northd/inc-proc-northd.c \ northd/inc-proc-northd.h \ northd/ipam.c \ - northd/ipam.h + northd/ipam.h \ + northd/template-var.c \ + northd/template-var.h northd_ovn_northd_LDADD = \ lib/libovn.la \ $(OVSDB_LIBDIR)/libovsdb.la \ diff --git a/northd/en-northd.c b/northd/en-northd.c index 7fe83db642..030ee25d8f 100644 --- a/northd/en-northd.c +++ b/northd/en-northd.c @@ -80,6 +80,8 @@ void en_northd_run(struct engine_node *node, void *data) EN_OVSDB_GET(engine_get_input("NB_acl", node)); input_data.nbrec_static_mac_binding_table = EN_OVSDB_GET(engine_get_input("NB_static_mac_binding", node)); + input_data.nbrec_chassis_template_var_table = + EN_OVSDB_GET(engine_get_input("NB_chassis_template_var", node)); input_data.sbrec_sb_global_table = EN_OVSDB_GET(engine_get_input("SB_sb_global", node)); @@ -113,6 +115,8 @@ void en_northd_run(struct engine_node *node, void *data) EN_OVSDB_GET(engine_get_input("SB_chassis_private", node)); input_data.sbrec_static_mac_binding_table = EN_OVSDB_GET(engine_get_input("SB_static_mac_binding", node)); + input_data.sbrec_chassis_template_var_table = + EN_OVSDB_GET(engine_get_input("SB_chassis_template_var", node)); northd_run(&input_data, data, eng_ctx->ovnnb_idl_txn, diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c index 54e0ad3b05..da791f035d 100644 --- a/northd/inc-proc-northd.c +++ b/northd/inc-proc-northd.c @@ -64,7 +64,8 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_northd); NB_NODE(ha_chassis_group, "ha_chassis_group") \ NB_NODE(ha_chassis, "ha_chassis") \ NB_NODE(bfd, "bfd") \ - NB_NODE(static_mac_binding, "static_mac_binding") + NB_NODE(static_mac_binding, "static_mac_binding") \ + NB_NODE(chassis_template_var, "chassis_template_var") enum nb_engine_node { #define NB_NODE(NAME, NAME_STR) NB_##NAME, @@ -114,7 +115,8 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_northd); SB_NODE(load_balancer, "load_balancer") \ SB_NODE(bfd, "bfd") \ SB_NODE(fdb, "fdb") \ - SB_NODE(static_mac_binding, "static_mac_binding") + SB_NODE(static_mac_binding, "static_mac_binding") \ + SB_NODE(chassis_template_var, "chassis_template_var") enum sb_engine_node { #define SB_NODE(NAME, NAME_STR) SB_##NAME, @@ -186,6 +188,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, engine_add_input(&en_northd, &en_nb_ha_chassis_group, NULL); engine_add_input(&en_northd, &en_nb_ha_chassis, 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); @@ -215,6 +218,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, engine_add_input(&en_northd, &en_sb_load_balancer, NULL); 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_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); diff --git a/northd/northd.c b/northd/northd.c index b7388afc58..170b4f95c8 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -51,6 +51,7 @@ #include "lib/stopwatch-names.h" #include "stream.h" #include "timeval.h" +#include "template-var.h" #include "util.h" #include "uuid.h" #include "ovs-thread.h" @@ -15129,6 +15130,44 @@ sync_dns_entries(struct northd_input *input_data, } hmap_destroy(&dns_map); } + +static void +sync_template_vars(struct northd_input *input_data, + struct ovsdb_idl_txn *ovnsb_txn) +{ + struct template_var_table nb_tvs = TEMPLATE_VAR_TABLE_INITIALIZER(&nb_tvs); + + const struct nbrec_chassis_template_var *nb_tv; + const struct sbrec_chassis_template_var *sb_tv; + struct template_var *tv; + + NBREC_CHASSIS_TEMPLATE_VAR_TABLE_FOR_EACH ( + nb_tv, input_data->nbrec_chassis_template_var_table) { + template_var_insert(&nb_tvs, nb_tv); + } + + SBREC_CHASSIS_TEMPLATE_VAR_TABLE_FOR_EACH_SAFE ( + sb_tv, input_data->sbrec_chassis_template_var_table) { + tv = template_var_find(&nb_tvs, sb_tv->chassis); + if (!tv) { + sbrec_chassis_template_var_delete(sb_tv); + continue; + } + if (!smap_equal(&sb_tv->variables, &tv->nb->variables)) { + sbrec_chassis_template_var_set_variables(sb_tv, + &tv->nb->variables); + } + template_var_remove(&nb_tvs, tv); + template_var_destroy(tv); + } + + TEMPLATE_VAR_TABLE_FOR_EACH (tv, &nb_tvs) { + sb_tv = sbrec_chassis_template_var_insert(ovnsb_txn); + sbrec_chassis_template_var_set_chassis(sb_tv, tv->nb->chassis); + sbrec_chassis_template_var_set_variables(sb_tv, &tv->nb->variables); + } + template_var_table_destroy(&nb_tvs); +} static void destroy_datapaths_and_ports(struct hmap *datapaths, struct hmap *ports, @@ -15645,6 +15684,8 @@ ovnnb_db_run(struct northd_input *input_data, sync_port_groups(input_data, ovnsb_txn, &data->port_groups); sync_meters(input_data, ovnsb_txn, &data->meter_groups); sync_dns_entries(input_data, ovnsb_txn, &data->datapaths); + sync_template_vars(input_data, ovnsb_txn); + cleanup_stale_fdb_entries(input_data, &data->datapaths); stopwatch_stop(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); diff --git a/northd/northd.h b/northd/northd.h index da90e28155..1935c80d40 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -36,6 +36,8 @@ struct northd_input { const struct nbrec_acl_table *nbrec_acl_table; const struct nbrec_static_mac_binding_table *nbrec_static_mac_binding_table; + const struct nbrec_chassis_template_var_table + *nbrec_chassis_template_var_table; /* Southbound table references */ const struct sbrec_sb_global_table *sbrec_sb_global_table; @@ -55,6 +57,8 @@ struct northd_input { const struct sbrec_chassis_private_table *sbrec_chassis_private_table; const struct sbrec_static_mac_binding_table *sbrec_static_mac_binding_table; + const struct sbrec_chassis_template_var_table + *sbrec_chassis_template_var_table; /* Indexes */ struct ovsdb_idl_index *sbrec_chassis_by_name; diff --git a/northd/template-var.c b/northd/template-var.c new file mode 100644 index 0000000000..a1069a5b51 --- /dev/null +++ b/northd/template-var.c @@ -0,0 +1,74 @@ +/* Copyright (c) 2022, Red Hat, Inc. + * + * 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 "template-var.h" + +struct template_var_table * +template_var_table_create(void) +{ + struct template_var_table *table = xmalloc(sizeof *table); + + hmap_init(&table->vars); + return table; +} + +void +template_var_table_destroy(struct template_var_table *table) +{ + struct template_var *tv; + + HMAP_FOR_EACH_POP (tv, hmap_node, &table->vars) { + template_var_destroy(tv); + } + hmap_destroy(&table->vars); +} + +void +template_var_insert(struct template_var_table *table, + const struct nbrec_chassis_template_var *nbrec_tv) +{ + struct template_var *tv = xmalloc(sizeof *tv); + tv->nb = nbrec_tv; + hmap_insert(&table->vars, &tv->hmap_node, + template_var_hash(nbrec_tv->chassis)); +} + +struct template_var * +template_var_find(struct template_var_table *table, const char *chassis_name) +{ + struct template_var *tv; + + HMAP_FOR_EACH_WITH_HASH (tv, hmap_node, template_var_hash(chassis_name), + &table->vars) { + if (!strcmp(chassis_name, tv->nb->chassis)) { + return tv; + } + } + return NULL; +} + +void +template_var_remove(struct template_var_table *table, struct template_var *tv) +{ + hmap_remove(&table->vars, &tv->hmap_node); +} + +void +template_var_destroy(struct template_var *tv) +{ + free(tv); +} diff --git a/northd/template-var.h b/northd/template-var.h new file mode 100644 index 0000000000..2de0e6cfe4 --- /dev/null +++ b/northd/template-var.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2022, Red Hat, Inc. + * + * 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. + */ + +#ifndef OVN_NORTHD_TEMPLATE_VAR_H +#define OVN_NORTHD_TEMPLATE_VAR_H 1 + +#include "openvswitch/hmap.h" +#include "lib/ovn-nb-idl.h" + +struct template_var { + struct hmap_node hmap_node; + + const struct nbrec_chassis_template_var *nb; +}; + +struct template_var_table { + struct hmap vars; +}; + +#define TEMPLATE_VAR_TABLE_INITIALIZER(TBL) \ + { .vars = HMAP_INITIALIZER(&(TBL)->vars) } + +#define TEMPLATE_VAR_TABLE_FOR_EACH(NODE, TBL) \ + HMAP_FOR_EACH (NODE, hmap_node, &(TBL)->vars) + +struct template_var_table *template_var_table_create(void); +void template_var_table_destroy(struct template_var_table *); + +static inline uint32_t +template_var_hash(const char *tv_chassis) +{ + return hash_string(tv_chassis, 0); +} + +void template_var_insert(struct template_var_table *, + const struct nbrec_chassis_template_var *); + +struct template_var * +template_var_find(struct template_var_table *, const char *chassis_name); + +void template_var_remove(struct template_var_table *, + struct template_var *); + +void template_var_destroy(struct template_var *); + +#endif /* OVN_NORTHD_TEMPLATE_VAR_H 1 */ diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema index 174364c8b1..6f9d38f47b 100644 --- a/ovn-nb.ovsschema +++ b/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", - "version": "6.3.0", - "cksum": "4042813038 31869", + "version": "6.4.0", + "cksum": "3512158873 32360", "tables": { "NB_Global": { "columns": { @@ -620,6 +620,17 @@ "mac": {"type": "string"}, "override_dynamic_mac": {"type": "boolean"}}, "indexes": [["logical_port", "ip"]], - "isRoot": true} + "isRoot": true}, + "Chassis_Template_Var": { + "columns": { + "chassis": {"type": "string"}, + "variables": { + "type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}, + "external_ids": { + "type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}}, + "indexes": [["chassis"]], + "isRoot": true} } } diff --git a/ovn-nb.xml b/ovn-nb.xml index f41e9d7c0e..45b75e66df 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -4436,4 +4436,33 @@ </column> </group> </table> + + <table name="Chassis_Template_Var"> + <p> + One record per chassis, each containing a map, <code>variables</code>, + between template variable names and their value for that specific + chassis. A template variable has a name and potentially different + values on different hypervisors in the OVN cluster. For example, + two rows, <code>R1 = (.chassis=C1, variables={(N: V1)}</code> and + <code>R2 = (.chassis=C2, variables={(N: V2)}</code> will make + <code>ovn-controller</code> running on chassis <code>C1</code> and + <code>C2</code> interpret the token <code>N</code> either as + <code>V1</code> (on <code>C1</code>) or as <code>V2</code> (on + <code>C2</code>). Users can refer to template variables from + within other logical components, e.g., within ACL, QoS or + Logical_Router_Policy matches or from Load_Balancer VIP and + backend definitions. + </p> + <column name="chassis"> + The chassis this set of variable values applies to. + </column> + <column name="variables"> + The set of variable values for a given chassis. + </column> + <group title="Common Columns"> + <column name="external_ids"> + See <em>External IDs</em> at the beginning of this document. + </column> + </group> + </table> </database> diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema index 576ebbdeb0..95c7c2d7e3 100644 --- a/ovn-sb.ovsschema +++ b/ovn-sb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Southbound", - "version": "20.25.0", - "cksum": "53184112 28845", + "version": "20.26.0", + "cksum": "3311869408 29176", "tables": { "SB_Global": { "columns": { @@ -565,6 +565,14 @@ "key": {"type": "uuid", "refTable": "Datapath_Binding"}}}}, "indexes": [["logical_port", "ip"]], + "isRoot": true}, + "Chassis_Template_Var": { + "columns": { + "chassis": {"type": "string"}, + "variables": { + "type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}}, + "indexes": [["chassis"]], "isRoot": true} } } diff --git a/ovn-sb.xml b/ovn-sb.xml index 315d608534..169a53aaa9 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -4801,4 +4801,19 @@ tcp.flags = RST; The logical datapath to which the logical router port belongs. </column> </table> + + <table name="Chassis_Template_Var"> + <p> + Each record represents the set of template variable instantiations + for a given chassis and is populated by <code>ovn-northd</code> + from the contents of the <code>OVN_Northbound.Chassis_Template_Var</code> + table. + </p> + <column name="chassis"> + The chassis this set of variable values applies to. + </column> + <column name="variables"> + The set of variable values for a given chassis. + </column> + </table> </database> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 4f399eccb6..c7112b805d 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -7929,3 +7929,38 @@ AT_CHECK([grep "lr_in_arp_resolve" R1flows | grep priority=90 | sort], [0], [dnl AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([NB to SB Chassis_Template_Var propagation]) +AT_KEYWORDS([templates]) +ovn_start + +AT_CHECK([ovn-nbctl create Chassis_Template_Var chassis="hv1"], [0], [ignore]) +AT_CHECK([ovn-nbctl create Chassis_Template_Var chassis="hv2"], [0], [ignore]) + +check ovn-nbctl set Chassis_Template_Var hv1 variables:tv=v1 +check ovn-nbctl set Chassis_Template_Var hv2 variables:tv=v2 + +AS_BOX([Ensure values are propagated to SB]) +check ovn-nbctl --wait=sb sync +check_column "tv=v1" sb:Chassis_Template_Var variables chassis="hv1" +check_column "tv=v2" sb:Chassis_Template_Var variables chassis="hv2" + +AS_BOX([Ensure SB is reconciled]) +check ovn-sbctl --all destroy Chassis_Template_Var +check ovn-nbctl --wait=sb sync +check_column "tv=v1" sb:Chassis_Template_Var variables chassis="hv1" +check_column "tv=v2" sb:Chassis_Template_Var variables chassis="hv2" + +AS_BOX([Ensure SB is reconciled - deletion]) +check ovn-nbctl destroy Chassis_Template_Var hv1 +check ovn-nbctl --wait=sb sync +check_column "tv=v2" sb:Chassis_Template_Var variables chassis="hv2" + +AS_BOX([Ensure SB is reconciled - cleanup]) +check ovn-nbctl destroy Chassis_Template_Var hv2 +check ovn-nbctl --wait=sb sync +check_row_count sb:Chassis_Template_Var 0 + +AT_CLEANUP +]) diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index 811468dc66..d2dee6b31c 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -7300,6 +7300,9 @@ static const struct ctl_table_class tables[NBREC_N_TABLES] = { [NBREC_TABLE_NAT].row_ids[0] = {&nbrec_nat_col_external_ip, NULL, NULL}, + [NBREC_TABLE_CHASSIS_TEMPLATE_VAR].row_ids[0] + = {&nbrec_chassis_template_var_col_chassis, NULL, NULL}, + [NBREC_TABLE_CONNECTION].row_ids[0] = {&nbrec_connection_col_target, NULL, NULL}, }; diff --git a/utilities/ovn-sbctl.c b/utilities/ovn-sbctl.c index f60dde1b67..00b2f785a5 100644 --- a/utilities/ovn-sbctl.c +++ b/utilities/ovn-sbctl.c @@ -1457,6 +1457,9 @@ static const struct ctl_table_class tables[SBREC_N_TABLES] = { [SBREC_TABLE_LOAD_BALANCER].row_ids[0] = {&sbrec_load_balancer_col_name, NULL, NULL}, + + [SBREC_TABLE_CHASSIS_TEMPLATE_VAR].row_ids[0] + = {&sbrec_chassis_template_var_col_chassis, NULL, NULL}, }; static const struct ctl_command_syntax sbctl_commands[] = { _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev