Message ID | 20240111153428.2790587-1-numans@ovn.org |
---|---|
State | Superseded |
Headers | show |
Series | northd lflow incremental processing | expand |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | success | apply and check: success |
ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
ovsrobot/github-robot-_ovn-kubernetes | success | github build: passed |
On 1/11/24 16:34, numans@ovn.org wrote: > From: Numan Siddique <numans@ovn.org> > > Any changes to northd engine node due to load balancers > are now handled in 'sync_to_sb_lb' node to sync the changed > load balancers to SB load balancers. > > The logic to sync the SB load balancers is changed a bit and it > now mimics the SB lflow sync. > > Below are the scale testing results done with all the patches applied > in this series using ovn-heater. The test ran the scenario - > ocp-500-density-heavy.yml [1]. > > The resuts are: > > ------------------------------------------------------------------------------------------------------------------------------------------------------- > Min (s) Median (s) 90%ile (s) 99%ile (s) Max (s) Mean (s) Total (s) Count Failed > ------------------------------------------------------------------------------------------------------------------------------------------------------- > Iteration Total 0.136883 1.129016 1.192001 1.204167 1.212728 0.665017 83.127099 125 0 > Namespace.add_ports 0.005216 0.005736 0.007034 0.015486 0.018978 0.006211 0.776373 125 0 > WorkerNode.bind_port 0.035030 0.046082 0.052469 0.058293 0.060311 0.045973 11.493259 250 0 > WorkerNode.ping_port 0.005057 0.006727 1.047692 1.069253 1.071336 0.266896 66.724094 250 0 > ------------------------------------------------------------------------------------------------------------------------------------------------------- > > The results with the present main [2] are: > > ------------------------------------------------------------------------------------------------------------------------------------------------------- > Min (s) Median (s) 90%ile (s) 99%ile (s) Max (s) Mean (s) Total (s) Count Failed > ------------------------------------------------------------------------------------------------------------------------------------------------------- > Iteration Total 0.135491 2.223805 3.311270 3.339078 3.345346 1.729172 216.146495 125 0 > Namespace.add_ports 0.005380 0.005744 0.006819 0.018773 0.020800 0.006292 0.786532 125 0 > WorkerNode.bind_port 0.034179 0.046055 0.053488 0.058801 0.071043 0.046117 11.529311 250 0 > WorkerNode.ping_port 0.004956 0.006952 3.086952 3.191743 3.192807 0.791544 197.886026 250 0 > ------------------------------------------------------------------------------------------------------------------------------------------------------- > > [1] - https://github.com/ovn-org/ovn-heater/blob/main/test-scenarios/ocp-500-density-heavy.yml > [2] - 2a12cda890a7("controller, northd: Wait for cleanup before replying to exit") > > Signed-off-by: Numan Siddique <numans@ovn.org> > --- Hi Numan, I only have a few minor comments, please see inline. With those addressed I think the patch is correct: Acked-by: Dumitru Ceara <dceara@redhat.com> Thanks, Dumitru > northd/en-sync-sb.c | 505 +++++++++++++++++++++++++++++++++++++-- > northd/inc-proc-northd.c | 1 + > northd/lflow-mgr.c | 196 ++++++--------- > northd/lflow-mgr.h | 23 +- > northd/northd.c | 238 ------------------ > northd/northd.h | 6 - > tests/ovn-northd.at | 164 ++++++++++--- > 7 files changed, 705 insertions(+), 428 deletions(-) > > diff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c > index d39cbbf2e6..80f3621bb9 100644 > --- a/northd/en-sync-sb.c > +++ b/northd/en-sync-sb.c > @@ -18,17 +18,21 @@ > #include <stdlib.h> > #include <stdio.h> > > +/* OVS includes. */ > #include "lib/svec.h" > #include "openvswitch/util.h" > > +/* OVN includes. */ > #include "en-lr-nat.h" > #include "en-lr-stateful.h" > #include "en-sync-sb.h" > +#include "lb.h" > #include "lib/inc-proc-eng.h" > #include "lib/lb.h" > #include "lib/ovn-nb-idl.h" > #include "lib/ovn-sb-idl.h" > #include "lib/ovn-util.h" > +#include "lflow-mgr.h" > #include "northd.h" > > #include "openvswitch/vlog.h" > @@ -51,6 +55,40 @@ static void build_port_group_address_set(const struct nbrec_port_group *, > struct svec *ipv4_addrs, > struct svec *ipv6_addrs); > > +struct sb_lb_table; > +struct sb_lb_record; These are defined just below. Let's move the prototypes after the struct definition? > +static void sb_lb_table_init(struct sb_lb_table *); > +static void sb_lb_table_clear(struct sb_lb_table *); > +static void sb_lb_table_destroy(struct sb_lb_table *); > + > +static struct sb_lb_record *sb_lb_table_find(struct hmap *sb_lbs, > + const struct uuid *); > +static void sb_lb_table_build_and_sync(struct sb_lb_table *, > + struct ovsdb_idl_txn *ovnsb_txn, > + const struct sbrec_load_balancer_table *, > + const struct sbrec_logical_dp_group_table *, > + struct hmap *lb_dps_map, > + struct ovn_datapaths *ls_datapaths, > + struct ovn_datapaths *lr_datapaths, > + struct chassis_features *); Nit: indentation > +static bool sync_sb_lb_record(struct sb_lb_record *, > + const struct sbrec_load_balancer *, > + const struct sbrec_logical_dp_group_table *, > + struct sb_lb_table *, > + struct ovsdb_idl_txn *ovnsb_txn, > + struct ovn_datapaths *ls_datapaths, > + struct ovn_datapaths *lr_datapaths, > + struct chassis_features *); > +static bool sync_changed_lbs(struct sb_lb_table *, > + struct ovsdb_idl_txn *ovnsb_txn, > + const struct sbrec_load_balancer_table *, > + const struct sbrec_logical_dp_group_table *, > + struct tracked_lbs *, > + struct ovn_datapaths *ls_datapaths, > + struct ovn_datapaths *lr_datapaths, > + struct chassis_features *); > +static bool check_sb_lb_duplicates(const struct sbrec_load_balancer_table *); > + > void * > en_sync_to_sb_init(struct engine_node *node OVS_UNUSED, > struct engine_arg *arg OVS_UNUSED) > @@ -206,49 +244,99 @@ sync_to_sb_addr_set_nb_port_group_handler(struct engine_node *node, > /* sync_to_sb_lb engine node functions. > * This engine node syncs the SB load balancers. > */ > +struct sb_lb_record { > + struct hmap_node key_node; /* Index on 'nblb->header_.uuid'. */ > + > + struct ovn_lb_datapaths *lb_dps; > + const struct sbrec_load_balancer *sbrec_lb; > + struct ovn_dp_group *ls_dpg; > + struct ovn_dp_group *lr_dpg; > + struct uuid sb_uuid; > +}; > + > +struct sb_lb_table { > + struct hmap entries; /* Stores struct sb_lb_record. */ > + struct hmap ls_dp_groups; > + struct hmap lr_dp_groups; > +}; > + > +struct ed_type_sync_to_sb_lb_data { > + struct sb_lb_table sb_lbs; > +}; > + > void * > en_sync_to_sb_lb_init(struct engine_node *node OVS_UNUSED, > struct engine_arg *arg OVS_UNUSED) > { > - return NULL; > + struct ed_type_sync_to_sb_lb_data *data = xzalloc(sizeof *data); > + sb_lb_table_init(&data->sb_lbs); > + > + return data; > } > > void > -en_sync_to_sb_lb_run(struct engine_node *node, void *data OVS_UNUSED) > +en_sync_to_sb_lb_run(struct engine_node *node, void *data_) > { > + struct northd_data *northd_data = engine_get_input_data("northd", node); > const struct sbrec_load_balancer_table *sb_load_balancer_table = > EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); > + const struct sbrec_logical_dp_group_table *sb_dpgrp_table = > + EN_OVSDB_GET(engine_get_input("SB_logical_dp_group", node)); > const struct engine_context *eng_ctx = engine_get_context(); > - struct northd_data *northd_data = engine_get_input_data("northd", node); > + struct ed_type_sync_to_sb_lb_data *data = data_; > + > + sb_lb_table_clear(&data->sb_lbs); > + sb_lb_table_build_and_sync(&data->sb_lbs, eng_ctx->ovnsb_idl_txn, > + sb_load_balancer_table, > + sb_dpgrp_table, > + &northd_data->lb_datapaths_map, > + &northd_data->ls_datapaths, > + &northd_data->lr_datapaths, > + &northd_data->features); > > - 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); > engine_set_node_state(node, EN_UPDATED); > } > > void > -en_sync_to_sb_lb_cleanup(void *data OVS_UNUSED) > +en_sync_to_sb_lb_cleanup(void *data_) > { > - > + struct ed_type_sync_to_sb_lb_data *data = data_; > + sb_lb_table_destroy(&data->sb_lbs); > } > > bool > -sync_to_sb_lb_northd_handler(struct engine_node *node, void *data OVS_UNUSED) > +sync_to_sb_lb_northd_handler(struct engine_node *node, void *data_) > { > struct northd_data *nd = engine_get_input_data("northd", node); > > - if (!northd_has_tracked_data(&nd->trk_data) || > - northd_has_lbs_in_tracked_data(&nd->trk_data)) { > - /* Return false if no tracking data or if lbs changed. */ > + if (!northd_has_tracked_data(&nd->trk_data)) { > + /* Return false if no tracking data. */ > return false; > } > > + if (!northd_has_lbs_in_tracked_data(&nd->trk_data)) { > + return true; > + } > > - /* There are only NB LSP related changes and these can be safely > - * ignore and returned true. However in case the northd engine > - * tracking data includes other changes, we need to do additional > - * checks before safely ignoring. */ > + const struct engine_context *eng_ctx = engine_get_context(); > + if (!eng_ctx->ovnsb_idl_txn) { > + return false; > + } This will never be hit. AFAICT we run the incremental processing engine only if we can commit to the SB, i.e., ovnsb_idl_txn != NULL. > + > + const struct sbrec_logical_dp_group_table *sb_dpgrp_table = > + EN_OVSDB_GET(engine_get_input("SB_logical_dp_group", node)); > + const struct sbrec_load_balancer_table *sb_lb_table = > + EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); > + struct ed_type_sync_to_sb_lb_data *data = data_; > + > + if (!sync_changed_lbs(&data->sb_lbs, eng_ctx->ovnsb_idl_txn, sb_lb_table, > + sb_dpgrp_table, &nd->trk_data.trk_lbs, > + &nd->ls_datapaths, &nd->lr_datapaths, > + &nd->features)) { > + return false; > + } > + > + engine_set_node_state(node, EN_UPDATED); > return true; > } > > @@ -519,3 +607,388 @@ sb_address_set_lookup_by_name(struct ovsdb_idl_index *sbrec_addr_set_by_name, > > return retval; > } > + > +/* static functions related to sync_to_sb_lb */ > + > +static void > +sb_lb_table_init(struct sb_lb_table *sb_lbs) > +{ > + hmap_init(&sb_lbs->entries); > + ovn_dp_groups_init(&sb_lbs->ls_dp_groups); > + ovn_dp_groups_init(&sb_lbs->lr_dp_groups); > +} > + > +static void > +sb_lb_table_clear(struct sb_lb_table *sb_lbs) > +{ > + struct sb_lb_record *sb_lb; > + HMAP_FOR_EACH_POP (sb_lb, key_node, &sb_lbs->entries) { > + free(sb_lb); > + } > + > + ovn_dp_groups_clear(&sb_lbs->ls_dp_groups); > + ovn_dp_groups_clear(&sb_lbs->lr_dp_groups); > +} > + > +static void > +sb_lb_table_destroy(struct sb_lb_table *sb_lbs) > +{ > + sb_lb_table_clear(sb_lbs); > + hmap_destroy(&sb_lbs->entries); > + ovn_dp_groups_destroy(&sb_lbs->ls_dp_groups); > + ovn_dp_groups_destroy(&sb_lbs->lr_dp_groups); > +} > + > +static struct sb_lb_record * > +sb_lb_table_find(struct hmap *sb_lbs, const struct uuid *lb_uuid) > +{ > + struct sb_lb_record *sb_lb; > + HMAP_FOR_EACH_WITH_HASH (sb_lb, key_node, uuid_hash(lb_uuid), > + sb_lbs) { > + if (uuid_equals(&sb_lb->lb_dps->lb->nlb->header_.uuid, lb_uuid)) { > + return sb_lb; > + } > + } > + > + return NULL; > +} > + > +static void > +sb_lb_table_build_and_sync(struct sb_lb_table *sb_lbs, > + struct ovsdb_idl_txn *ovnsb_txn, > + const struct sbrec_load_balancer_table *sb_lb_table, > + const struct sbrec_logical_dp_group_table *sb_dpgrp_table, > + struct hmap *lb_dps_map, > + struct ovn_datapaths *ls_datapaths, > + struct ovn_datapaths *lr_datapaths, > + struct chassis_features *chassis_features) > +{ > + struct hmap tmp_sb_lbs = HMAP_INITIALIZER(&tmp_sb_lbs); > + struct ovn_lb_datapaths *lb_dps; > + struct sb_lb_record *sb_lb; > + > + HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) { > + if (!lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { > + continue; > + } > + > + sb_lb = xzalloc(sizeof *sb_lb); > + sb_lb->lb_dps = lb_dps; > + hmap_insert(&tmp_sb_lbs, &sb_lb->key_node, > + uuid_hash(&lb_dps->lb->nlb->header_.uuid)); > + } > + > + const struct sbrec_load_balancer *sbrec_lb; > + SBREC_LOAD_BALANCER_TABLE_FOR_EACH_SAFE (sbrec_lb, > + sb_lb_table) { > + const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); > + struct uuid lb_uuid; > + if (!nb_lb_uuid || !uuid_from_string(&lb_uuid, nb_lb_uuid)) { > + sbrec_load_balancer_delete(sbrec_lb); > + continue; > + } > + > + sb_lb = sb_lb_table_find(&tmp_sb_lbs, &lb_uuid); > + if (sb_lb) { > + sb_lb->sbrec_lb = sbrec_lb; > + bool success = sync_sb_lb_record(sb_lb, sbrec_lb, sb_dpgrp_table, > + sb_lbs, ovnsb_txn, ls_datapaths, > + lr_datapaths, chassis_features); > + /* Since we are rebuilding and syncing, sync_sb_lb_record should > + * not return false. */ > + ovs_assert(success); > + > + hmap_remove(&tmp_sb_lbs, &sb_lb->key_node); > + hmap_insert(&sb_lbs->entries, &sb_lb->key_node, > + uuid_hash(&sb_lb->lb_dps->lb->nlb->header_.uuid)); > + } else { > + sbrec_load_balancer_delete(sbrec_lb); > + } > + } > + > + HMAP_FOR_EACH_POP (sb_lb, key_node, &tmp_sb_lbs) { > + bool success = sync_sb_lb_record(sb_lb, NULL, sb_dpgrp_table, sb_lbs, > + ovnsb_txn, ls_datapaths, lr_datapaths, > + chassis_features); > + /* Since we are rebuilding and syncing, sync_sb_lb_record should not > + * return false. */ > + ovs_assert(success); > + > + hmap_insert(&sb_lbs->entries, &sb_lb->key_node, > + uuid_hash(&sb_lb->lb_dps->lb->nlb->header_.uuid)); > + } > + > + hmap_destroy(&tmp_sb_lbs); > +} > + > +static bool > +sync_sb_lb_record(struct sb_lb_record *sb_lb, > + const struct sbrec_load_balancer *sbrec_lb, > + const struct sbrec_logical_dp_group_table *sb_dpgrp_table, > + struct sb_lb_table *sb_lbs, > + struct ovsdb_idl_txn *ovnsb_txn, > + struct ovn_datapaths *ls_datapaths, > + struct ovn_datapaths *lr_datapaths, > + struct chassis_features *chassis_features) > +{ > + struct sbrec_logical_dp_group *sbrec_ls_dp_group = NULL; > + struct sbrec_logical_dp_group *sbrec_lr_dp_group = NULL; > + const struct ovn_lb_datapaths *lb_dps; > + struct ovn_dp_group *pre_sync_ls_dpg; > + struct ovn_dp_group *pre_sync_lr_dpg; > + > + lb_dps = sb_lb->lb_dps; > + pre_sync_ls_dpg = sb_lb->ls_dpg; > + pre_sync_lr_dpg = sb_lb->lr_dpg; > + > + if (!sbrec_lb) { > + sb_lb->sb_uuid = uuid_random(); > + sbrec_lb = sbrec_load_balancer_insert_persist_uuid(ovnsb_txn, > + &sb_lb->sb_uuid); > + char *lb_id = xasprintf( > + UUID_FMT, UUID_ARGS(&lb_dps->lb->nlb->header_.uuid)); > + const struct smap external_ids = > + SMAP_CONST1(&external_ids, "lb_id", lb_id); > + sbrec_load_balancer_set_external_ids(sbrec_lb, &external_ids); > + free(lb_id); > + } else { > + sb_lb->sb_uuid = sbrec_lb->header_.uuid; > + sbrec_ls_dp_group = > + chassis_features->ls_dpg_column > + ? sbrec_lb->ls_datapath_group > + : sbrec_lb->datapath_group; /* deprecated */ > + > + sbrec_lr_dp_group = sbrec_lb->lr_datapath_group; > + } > + > + if (lb_dps->n_nb_ls) { > + sb_lb->ls_dpg = ovn_dp_group_get(&sb_lbs->ls_dp_groups, > + lb_dps->n_nb_ls, > + lb_dps->nb_ls_map, > + ods_size(ls_datapaths)); > + if (sb_lb->ls_dpg) { > + /* Update the dpg's sb dp_group. */ > + sb_lb->ls_dpg->dp_group = > + sbrec_logical_dp_group_table_get_for_uuid(sb_dpgrp_table, > + &sb_lb->ls_dpg->dpg_uuid); > + if (!sb_lb->ls_dpg->dp_group) { > + /* Ideally this should not happen. But it can still happen > + * due to 2 reasons: > + * 1. There is a bug in the dp_group management. We should > + * perhaps assert here. > + * 2. A User or CMS may delete the logical_dp_groups in SB DB > + * or clear the SB:Load_balancer.ls_datapath_group column > + * (intentionally or accidentally) > + * > + * Because of (2) it is better to return false instead of > + * assert,so that we recover from th inconsistent SB DB. > + */ > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > + VLOG_WARN_RL(&rl, "SB Load balancer [%s]'s ls_dp_group column " > + "is not set (which is unexpected). It should " > + "have been referencing the dp group ["UUID_FMT"]", > + sb_lb->lb_dps->lb->nlb->name, > + UUID_ARGS(&sb_lb->ls_dpg->dpg_uuid)); > + return false; > + } > + } else { > + sb_lb->ls_dpg = ovn_dp_group_create( > + ovnsb_txn, &sb_lbs->ls_dp_groups, sbrec_ls_dp_group, > + lb_dps->n_nb_ls, lb_dps->nb_ls_map, > + ods_size(ls_datapaths), true, > + ls_datapaths, lr_datapaths); > + } > + > + if (chassis_features->ls_dpg_column) { > + sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, > + sb_lb->ls_dpg->dp_group); > + sbrec_load_balancer_set_datapath_group(sbrec_lb, NULL); > + } else { > + /* datapath_group column is deprecated. */ > + sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, NULL); > + sbrec_load_balancer_set_datapath_group(sbrec_lb, > + sb_lb->ls_dpg->dp_group); > + > + } > + } else { > + sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, NULL); > + sbrec_load_balancer_set_datapath_group(sbrec_lb, NULL); > + } > + > + > + if (lb_dps->n_nb_lr) { > + sb_lb->lr_dpg = ovn_dp_group_get(&sb_lbs->lr_dp_groups, > + lb_dps->n_nb_lr, > + lb_dps->nb_lr_map, > + ods_size(lr_datapaths)); > + if (sb_lb->lr_dpg) { > + /* Update the dpg's sb dp_group. */ > + sb_lb->lr_dpg->dp_group = > + sbrec_logical_dp_group_table_get_for_uuid(sb_dpgrp_table, > + &sb_lb->lr_dpg->dpg_uuid); > + if (!sb_lb->lr_dpg->dp_group) { > + /* Ideally this should not happen. But it can still happen > + * due to 2 reasons: > + * 1. There is a bug in the dp_group management. We should > + * perhaps assert here. > + * 2. A User or CMS may delete the logical_dp_groups in SB DB > + * or clear the SB:Load_balancer.lr_datapath_group column > + * (intentionally or accidentally) > + * > + * Because of (2) it is better to return false instead of > + * assert,so that we recover from th inconsistent SB DB. > + */ > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > + VLOG_WARN_RL(&rl, "SB Load balancer [%s]'s lr_dp_group column " > + "is not set (which is unexpected). It should " > + "have been referencing the dp group ["UUID_FMT"]", > + sb_lb->lb_dps->lb->nlb->name, > + UUID_ARGS(&sb_lb->lr_dpg->dpg_uuid)); > + return false; > + } > + } else { > + sb_lb->lr_dpg = ovn_dp_group_create( > + ovnsb_txn, &sb_lbs->lr_dp_groups, sbrec_lr_dp_group, > + lb_dps->n_nb_lr, lb_dps->nb_lr_map, > + ods_size(lr_datapaths), false, > + ls_datapaths, lr_datapaths); > + } > + > + sbrec_load_balancer_set_lr_datapath_group(sbrec_lb, > + sb_lb->lr_dpg->dp_group); > + } else { > + sbrec_load_balancer_set_lr_datapath_group(sbrec_lb, NULL); > + } > + > + if (pre_sync_ls_dpg != sb_lb->ls_dpg) { > + if (sb_lb->ls_dpg) { > + inc_ovn_dp_group_ref(sb_lb->ls_dpg); > + } > + if (pre_sync_ls_dpg) { > + dec_ovn_dp_group_ref(&sb_lbs->ls_dp_groups, pre_sync_ls_dpg); > + } > + } > + > + if (pre_sync_lr_dpg != sb_lb->lr_dpg) { > + if (sb_lb->lr_dpg) { > + inc_ovn_dp_group_ref(sb_lb->lr_dpg); > + } > + if (pre_sync_lr_dpg) { > + dec_ovn_dp_group_ref(&sb_lbs->lr_dp_groups, pre_sync_lr_dpg); > + } > + } > + > + /* Update columns. */ > + sbrec_load_balancer_set_name(sbrec_lb, lb_dps->lb->nlb->name); > + sbrec_load_balancer_set_vips(sbrec_lb, > + ovn_northd_lb_get_vips(lb_dps->lb)); > + sbrec_load_balancer_set_protocol(sbrec_lb, lb_dps->lb->nlb->protocol); > + > + /* Store the fact that northd provides the original (destination IP + > + * transport port) tuple. > + */ > + struct smap options; > + smap_clone(&options, &lb_dps->lb->nlb->options); > + smap_replace(&options, "hairpin_orig_tuple", "true"); > + sbrec_load_balancer_set_options(sbrec_lb, &options); > + /* Clearing 'datapaths' column, since 'dp_group' is in use. */ > + sbrec_load_balancer_set_datapaths(sbrec_lb, NULL, 0); > + smap_destroy(&options); > + > + return true; > +} > + > +static bool > +sync_changed_lbs(struct sb_lb_table *sb_lbs, > + struct ovsdb_idl_txn *ovnsb_txn, > + const struct sbrec_load_balancer_table *sb_lb_table, > + const struct sbrec_logical_dp_group_table *sb_dpgrp_table, > + struct tracked_lbs *trk_lbs, > + struct ovn_datapaths *ls_datapaths, > + struct ovn_datapaths *lr_datapaths, > + struct chassis_features *chassis_features) > +{ > + struct ovn_lb_datapaths *lb_dps; > + struct hmapx_node *hmapx_node; > + struct sb_lb_record *sb_lb; > + > + HMAPX_FOR_EACH (hmapx_node, &trk_lbs->deleted) { > + lb_dps = hmapx_node->data; > + > + sb_lb = sb_lb_table_find(&sb_lbs->entries, > + &lb_dps->lb->nlb->header_.uuid); > + if (sb_lb) { > + const struct sbrec_load_balancer *sbrec_lb = > + sbrec_load_balancer_table_get_for_uuid(sb_lb_table, > + &sb_lb->sb_uuid); > + if (sbrec_lb) { > + sbrec_load_balancer_delete(sbrec_lb); > + } > + > + hmap_remove(&sb_lbs->entries, &sb_lb->key_node); > + free(sb_lb); > + } > + } > + > + HMAPX_FOR_EACH (hmapx_node, &trk_lbs->crupdated) { > + lb_dps = hmapx_node->data; > + > + sb_lb = sb_lb_table_find(&sb_lbs->entries, > + &lb_dps->lb->nlb->header_.uuid); > + > + if (!sb_lb && !lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { > + continue; > + } > + > + if (!sb_lb) { > + sb_lb = xzalloc(sizeof *sb_lb); > + sb_lb->lb_dps = lb_dps; > + hmap_insert(&sb_lbs->entries, &sb_lb->key_node, > + uuid_hash(&lb_dps->lb->nlb->header_.uuid)); > + } else { > + sb_lb->sbrec_lb = > + sbrec_load_balancer_table_get_for_uuid(sb_lb_table, > + &sb_lb->sb_uuid); > + } > + > + if (sb_lb && !lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { > + const struct sbrec_load_balancer *sbrec_lb = > + sbrec_load_balancer_table_get_for_uuid(sb_lb_table, > + &sb_lb->sb_uuid); > + if (sbrec_lb) { > + sbrec_load_balancer_delete(sbrec_lb); > + } > + > + hmap_remove(&sb_lbs->entries, &sb_lb->key_node); > + free(sb_lb); > + } > + > + if (!sync_sb_lb_record(sb_lb, sb_lb->sbrec_lb, sb_dpgrp_table, sb_lbs, > + ovnsb_txn, ls_datapaths, lr_datapaths, > + chassis_features)) { > + return false; > + } > + } > + > + return true; > +} > + > +static bool > +check_sb_lb_duplicates(const struct sbrec_load_balancer_table *table) > +{ > + struct sset existing_nb_lb_uuids = > + SSET_INITIALIZER(&existing_nb_lb_uuids); > + const struct sbrec_load_balancer *sbrec_lb; > + bool duplicates = false; > + > + SBREC_LOAD_BALANCER_TABLE_FOR_EACH (sbrec_lb, table) { > + const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); > + if (nb_lb_uuid && !sset_add(&existing_nb_lb_uuids, nb_lb_uuid)) { > + duplicates = true; > + break; > + } > + } > + > + sset_destroy(&existing_nb_lb_uuids); > + return duplicates; > +} > diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c > index 40a9e5e06c..d215c7792b 100644 > --- a/northd/inc-proc-northd.c > +++ b/northd/inc-proc-northd.c > @@ -264,6 +264,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, > sync_to_sb_lb_northd_handler); > engine_add_input(&en_sync_to_sb_lb, &en_sb_load_balancer, > sync_to_sb_lb_sb_load_balancer); > + engine_add_input(&en_sync_to_sb_lb, &en_sb_logical_dp_group, NULL); > > engine_add_input(&en_sync_to_sb_pb, &en_northd, > sync_to_sb_pb_northd_handler); > diff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c > index d81b13a25c..d09dc7acb5 100644 > --- a/northd/lflow-mgr.c > +++ b/northd/lflow-mgr.c > @@ -70,21 +70,6 @@ static struct ovs_mutex *lflow_hash_lock(const struct hmap *lflow_table, > uint32_t hash); > static void lflow_hash_unlock(struct ovs_mutex *hash_lock); > > -static struct ovn_dp_group *ovn_dp_group_get( > - struct hmap *dp_groups, size_t desired_n, > - const unsigned long *desired_bitmap, > - size_t bitmap_len); > -static struct ovn_dp_group *ovn_dp_group_create( > - struct ovsdb_idl_txn *ovnsb_txn, struct hmap *dp_groups, > - struct sbrec_logical_dp_group *, size_t desired_n, > - const unsigned long *desired_bitmap, > - size_t bitmap_len, bool is_switch, > - const struct ovn_datapaths *ls_datapaths, > - const struct ovn_datapaths *lr_datapaths); > -static struct ovn_dp_group *ovn_dp_group_get( > - struct hmap *dp_groups, size_t desired_n, > - const unsigned long *desired_bitmap, > - size_t bitmap_len); > static struct sbrec_logical_dp_group *ovn_sb_insert_or_update_logical_dp_group( > struct ovsdb_idl_txn *ovnsb_txn, > struct sbrec_logical_dp_group *, > @@ -564,31 +549,81 @@ lflow_table_add_lflow_default_drop(struct lflow_table *lflow_table, > where, lflow_ref); > } > > -/* Given a desired bitmap, finds a datapath group in 'dp_groups'. If it > - * doesn't exist, creates a new one and adds it to 'dp_groups'. > +struct ovn_dp_group * > +ovn_dp_group_get(struct hmap *dp_groups, size_t desired_n, > + const unsigned long *desired_bitmap, > + size_t bitmap_len) > +{ > + uint32_t hash; > + > + hash = hash_int(desired_n, 0); > + return ovn_dp_group_find(dp_groups, desired_bitmap, bitmap_len, hash); > +} > + > +/* Creates a new datapath group and adds it to 'dp_groups'. > * If 'sb_group' is provided, function will try to re-use this group by > - * either taking it directly, or by modifying, if it's not already in use. */ > + * either taking it directly, or by modifying, if it's not already in use. > + * Caller should first call ovn_dp_group_get() before calling this function. */ > struct ovn_dp_group * > -ovn_dp_group_get_or_create(struct ovsdb_idl_txn *ovnsb_txn, > - struct hmap *dp_groups, > - struct sbrec_logical_dp_group *sb_group, > - size_t desired_n, > - const unsigned long *desired_bitmap, > - size_t bitmap_len, > - bool is_switch, > - const struct ovn_datapaths *ls_datapaths, > - const struct ovn_datapaths *lr_datapaths) > +ovn_dp_group_create(struct ovsdb_idl_txn *ovnsb_txn, > + struct hmap *dp_groups, > + struct sbrec_logical_dp_group *sb_group, > + size_t desired_n, > + const unsigned long *desired_bitmap, > + size_t bitmap_len, > + bool is_switch, > + const struct ovn_datapaths *ls_datapaths, > + const struct ovn_datapaths *lr_datapaths) > { > struct ovn_dp_group *dpg; > > - dpg = ovn_dp_group_get(dp_groups, desired_n, desired_bitmap, bitmap_len); > - if (dpg) { > - return dpg; > + bool update_dp_group = false, can_modify = false; > + unsigned long *dpg_bitmap; > + size_t i, n = 0; > + > + dpg_bitmap = sb_group ? bitmap_allocate(bitmap_len) : NULL; > + for (i = 0; sb_group && i < sb_group->n_datapaths; i++) { > + struct ovn_datapath *datapath_od; > + > + datapath_od = ovn_datapath_from_sbrec( > + ls_datapaths ? &ls_datapaths->datapaths : NULL, > + lr_datapaths ? &lr_datapaths->datapaths : NULL, > + sb_group->datapaths[i]); > + if (!datapath_od || ovn_datapath_is_stale(datapath_od)) { > + break; > + } > + bitmap_set1(dpg_bitmap, datapath_od->index); > + n++; > + } > + if (!sb_group || i != sb_group->n_datapaths) { > + /* No group or stale group. Not going to be used. */ > + update_dp_group = true; > + can_modify = true; > + } else if (!bitmap_equal(dpg_bitmap, desired_bitmap, bitmap_len)) { > + /* The group in Sb is different. */ > + update_dp_group = true; > + /* We can modify existing group if it's not already in use. */ > + can_modify = !ovn_dp_group_find(dp_groups, dpg_bitmap, > + bitmap_len, hash_int(n, 0)); > } > > - return ovn_dp_group_create(ovnsb_txn, dp_groups, sb_group, desired_n, > - desired_bitmap, bitmap_len, is_switch, > - ls_datapaths, lr_datapaths); > + bitmap_free(dpg_bitmap); > + > + dpg = xzalloc(sizeof *dpg); > + dpg->bitmap = bitmap_clone(desired_bitmap, bitmap_len); > + if (!update_dp_group) { > + dpg->dp_group = sb_group; > + } else { > + dpg->dp_group = ovn_sb_insert_or_update_logical_dp_group( > + ovnsb_txn, > + can_modify ? sb_group : NULL, > + desired_bitmap, > + is_switch ? ls_datapaths : lr_datapaths); > + } > + dpg->dpg_uuid = dpg->dp_group->header_.uuid; > + hmap_insert(dp_groups, &dpg->node, hash_int(desired_n, 0)); > + > + return dpg; > } > > void > @@ -987,24 +1022,6 @@ ovn_dp_group_find(const struct hmap *dp_groups, > return NULL; > } > > -static void > -inc_ovn_dp_group_ref(struct ovn_dp_group *dpg) > -{ > - dpg->refcnt++; > -} > - > -static void > -dec_ovn_dp_group_ref(struct hmap *dp_groups, struct ovn_dp_group *dpg) > -{ > - dpg->refcnt--; > - > - if (!dpg->refcnt) { > - hmap_remove(dp_groups, &dpg->node); > - free(dpg->bitmap); > - free(dpg); > - } > -} > - > static struct sbrec_logical_dp_group * > ovn_sb_insert_or_update_logical_dp_group( > struct ovsdb_idl_txn *ovnsb_txn, > @@ -1031,83 +1048,6 @@ ovn_sb_insert_or_update_logical_dp_group( > return dp_group; > } > > -static struct ovn_dp_group * > -ovn_dp_group_get(struct hmap *dp_groups, size_t desired_n, > - const unsigned long *desired_bitmap, > - size_t bitmap_len) > -{ > - uint32_t hash; > - > - hash = hash_int(desired_n, 0); > - return ovn_dp_group_find(dp_groups, desired_bitmap, bitmap_len, hash); > -} > - > -/* Creates a new datapath group and adds it to 'dp_groups'. > - * If 'sb_group' is provided, function will try to re-use this group by > - * either taking it directly, or by modifying, if it's not already in use. > - * Caller should first call ovn_dp_group_get() before calling this function. */ > -static struct ovn_dp_group * > -ovn_dp_group_create(struct ovsdb_idl_txn *ovnsb_txn, > - struct hmap *dp_groups, > - struct sbrec_logical_dp_group *sb_group, > - size_t desired_n, > - const unsigned long *desired_bitmap, > - size_t bitmap_len, > - bool is_switch, > - const struct ovn_datapaths *ls_datapaths, > - const struct ovn_datapaths *lr_datapaths) > -{ > - struct ovn_dp_group *dpg; > - > - bool update_dp_group = false, can_modify = false; > - unsigned long *dpg_bitmap; > - size_t i, n = 0; > - > - dpg_bitmap = sb_group ? bitmap_allocate(bitmap_len) : NULL; > - for (i = 0; sb_group && i < sb_group->n_datapaths; i++) { > - struct ovn_datapath *datapath_od; > - > - datapath_od = ovn_datapath_from_sbrec( > - ls_datapaths ? &ls_datapaths->datapaths : NULL, > - lr_datapaths ? &lr_datapaths->datapaths : NULL, > - sb_group->datapaths[i]); > - if (!datapath_od || ovn_datapath_is_stale(datapath_od)) { > - break; > - } > - bitmap_set1(dpg_bitmap, datapath_od->index); > - n++; > - } > - if (!sb_group || i != sb_group->n_datapaths) { > - /* No group or stale group. Not going to be used. */ > - update_dp_group = true; > - can_modify = true; > - } else if (!bitmap_equal(dpg_bitmap, desired_bitmap, bitmap_len)) { > - /* The group in Sb is different. */ > - update_dp_group = true; > - /* We can modify existing group if it's not already in use. */ > - can_modify = !ovn_dp_group_find(dp_groups, dpg_bitmap, > - bitmap_len, hash_int(n, 0)); > - } > - > - bitmap_free(dpg_bitmap); > - > - dpg = xzalloc(sizeof *dpg); > - dpg->bitmap = bitmap_clone(desired_bitmap, bitmap_len); > - if (!update_dp_group) { > - dpg->dp_group = sb_group; > - } else { > - dpg->dp_group = ovn_sb_insert_or_update_logical_dp_group( > - ovnsb_txn, > - can_modify ? sb_group : NULL, > - desired_bitmap, > - is_switch ? ls_datapaths : lr_datapaths); > - } > - dpg->dpg_uuid = dpg->dp_group->header_.uuid; > - hmap_insert(dp_groups, &dpg->node, hash_int(desired_n, 0)); > - > - return dpg; > -} > - > /* Adds an OVN datapath to a datapath group of existing logical flow. > * Version to use when hash bucket locking is NOT required or the corresponding > * hash lock is already taken. */ > diff --git a/northd/lflow-mgr.h b/northd/lflow-mgr.h > index f215891b97..00554ef78a 100644 > --- a/northd/lflow-mgr.h > +++ b/northd/lflow-mgr.h > @@ -157,7 +157,10 @@ ovn_dp_groups_init(struct hmap *dp_groups) > > void ovn_dp_groups_clear(struct hmap *dp_groups); > void ovn_dp_groups_destroy(struct hmap *dp_groups); > -struct ovn_dp_group *ovn_dp_group_get_or_create( > +struct ovn_dp_group *ovn_dp_group_get(struct hmap *dp_groups, size_t desired_n, > + const unsigned long *desired_bitmap, > + size_t bitmap_len); > +struct ovn_dp_group *ovn_dp_group_create( > struct ovsdb_idl_txn *ovnsb_txn, struct hmap *dp_groups, > struct sbrec_logical_dp_group *sb_group, > size_t desired_n, const unsigned long *desired_bitmap, > @@ -165,4 +168,22 @@ struct ovn_dp_group *ovn_dp_group_get_or_create( > const struct ovn_datapaths *ls_datapaths, > const struct ovn_datapaths *lr_datapaths); > > +static inline void > +inc_ovn_dp_group_ref(struct ovn_dp_group *dpg) > +{ > + dpg->refcnt++; > +} > + > +static inline void > +dec_ovn_dp_group_ref(struct hmap *dp_groups, struct ovn_dp_group *dpg) > +{ > + dpg->refcnt--; > + > + if (!dpg->refcnt) { > + hmap_remove(dp_groups, &dpg->node); > + free(dpg->bitmap); > + free(dpg); > + } > +} > + > #endif /* LFLOW_MGR_H */ > \ No newline at end of file > diff --git a/northd/northd.c b/northd/northd.c > index 96a5b52127..d21a070fdd 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -3745,244 +3745,6 @@ build_lb_port_related_data( > build_lswitch_lbs_from_lrouter(lr_datapaths, lb_dps_map, lb_group_dps_map); > } > > -struct sb_lb { > - struct hmap_node hmap_node; > - > - const struct sbrec_load_balancer *slb; > - struct ovn_dp_group *dpg; > - struct ovn_dp_group *lr_dpg; > - struct uuid lb_uuid; > -}; > - > -static struct sb_lb * > -find_slb_in_sb_lbs(struct hmap *sb_lbs, const struct uuid *lb_uuid) > -{ > - struct sb_lb *sb_lb; > - HMAP_FOR_EACH_WITH_HASH (sb_lb, hmap_node, uuid_hash(lb_uuid), sb_lbs) { > - if (uuid_equals(&sb_lb->lb_uuid, lb_uuid)) { > - return sb_lb; > - } > - } > - > - return NULL; > -} > - > -/* Syncs relevant load balancers (applied to logical switches) to the > - * Southbound database. > - */ > -void > -sync_lbs(struct ovsdb_idl_txn *ovnsb_txn, > - const struct sbrec_load_balancer_table *sbrec_load_balancer_table, > - struct ovn_datapaths *ls_datapaths, > - struct ovn_datapaths *lr_datapaths, > - struct hmap *lb_dps_map, > - struct chassis_features *chassis_features) > -{ > - struct hmap ls_dp_groups = HMAP_INITIALIZER(&ls_dp_groups); > - struct hmap lr_dp_groups = HMAP_INITIALIZER(&lr_dp_groups); > - struct ovn_lb_datapaths *lb_dps; > - struct hmap sb_lbs = HMAP_INITIALIZER(&sb_lbs); > - > - /* Delete any stale SB load balancer rows and create datapath > - * groups for existing ones. */ > - struct hmapx existing_lbs = HMAPX_INITIALIZER(&existing_lbs); > - const struct sbrec_load_balancer *sbrec_lb; > - SBREC_LOAD_BALANCER_TABLE_FOR_EACH_SAFE (sbrec_lb, > - sbrec_load_balancer_table) { > - const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); > - struct uuid lb_uuid; > - if (!nb_lb_uuid || !uuid_from_string(&lb_uuid, nb_lb_uuid)) { > - sbrec_load_balancer_delete(sbrec_lb); > - continue; > - } > - > - /* Delete any SB load balancer entries that refer to NB load balancers > - * that don't exist anymore or are not applied to switches/routers > - * anymore. > - * > - * There is also a special case in which duplicate LBs might be created > - * in the SB, e.g., due to the fact that OVSDB only ensures > - * "at-least-once" consistency for clustered database tables that > - * are not indexed in any way. > - */ > - lb_dps = ovn_lb_datapaths_find(lb_dps_map, &lb_uuid); > - if (!lb_dps || (!lb_dps->n_nb_ls && !lb_dps->n_nb_lr) || > - !hmapx_add(&existing_lbs, lb_dps)) { > - sbrec_load_balancer_delete(sbrec_lb); > - continue; > - } > - > - struct sb_lb *sb_lb = xzalloc(sizeof *sb_lb); > - sb_lb->lb_uuid = lb_uuid; > - sb_lb->slb = sbrec_lb; > - hmap_insert(&sb_lbs, &sb_lb->hmap_node, uuid_hash(&lb_uuid)); > - > - /* Find or create datapath group for this load balancer. */ > - if (lb_dps->n_nb_ls) { > - struct sbrec_logical_dp_group *ls_datapath_group > - = chassis_features->ls_dpg_column > - ? sb_lb->slb->ls_datapath_group > - : sb_lb->slb->datapath_group; /* deprecated */ > - sb_lb->dpg = ovn_dp_group_get_or_create( > - ovnsb_txn, &ls_dp_groups, > - ls_datapath_group, > - lb_dps->n_nb_ls, lb_dps->nb_ls_map, > - ods_size(ls_datapaths), true, > - ls_datapaths, NULL); > - } > - if (lb_dps->n_nb_lr) { > - sb_lb->lr_dpg = ovn_dp_group_get_or_create( > - ovnsb_txn, &lr_dp_groups, > - sb_lb->slb->lr_datapath_group, > - lb_dps->n_nb_lr, lb_dps->nb_lr_map, > - ods_size(lr_datapaths), false, > - NULL, lr_datapaths); > - } > - } > - hmapx_destroy(&existing_lbs); > - > - /* Create SB Load balancer records if not present and sync > - * the SB load balancer columns. */ > - HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) { > - > - if (!lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { > - continue; > - } > - > - /* Store the fact that northd provides the original (destination IP + > - * transport port) tuple. > - */ > - struct smap options; > - smap_clone(&options, &lb_dps->lb->nlb->options); > - smap_replace(&options, "hairpin_orig_tuple", "true"); > - > - struct sb_lb *sb_lb = find_slb_in_sb_lbs(&sb_lbs, > - &lb_dps->lb->nlb->header_.uuid); > - ovs_assert(!sb_lb || (sb_lb->slb && (sb_lb->dpg || sb_lb->lr_dpg))); > - struct ovn_dp_group *lb_dpg = NULL, *lb_lr_dpg = NULL; > - if (!sb_lb) { > - sbrec_lb = sbrec_load_balancer_insert(ovnsb_txn); > - char *lb_id = xasprintf( > - UUID_FMT, UUID_ARGS(&lb_dps->lb->nlb->header_.uuid)); > - const struct smap external_ids = > - SMAP_CONST1(&external_ids, "lb_id", lb_id); > - sbrec_load_balancer_set_external_ids(sbrec_lb, &external_ids); > - free(lb_id); > - } else { > - sbrec_lb = sb_lb->slb; > - lb_dpg = sb_lb->dpg; > - lb_lr_dpg = sb_lb->lr_dpg; > - } > - > - /* Find or create datapath group for this load balancer. */ > - if (!lb_dpg && lb_dps->n_nb_ls) { > - struct sbrec_logical_dp_group *ls_datapath_group > - = chassis_features->ls_dpg_column > - ? sbrec_lb->ls_datapath_group > - : sbrec_lb->datapath_group; /* deprecated */ > - lb_dpg = ovn_dp_group_get_or_create( > - ovnsb_txn, &ls_dp_groups, > - ls_datapath_group, > - lb_dps->n_nb_ls, lb_dps->nb_ls_map, > - ods_size(ls_datapaths), true, > - ls_datapaths, NULL); > - } > - if (!lb_lr_dpg && lb_dps->n_nb_lr) { > - lb_lr_dpg = ovn_dp_group_get_or_create( > - ovnsb_txn, &lr_dp_groups, > - sbrec_lb->lr_datapath_group, > - lb_dps->n_nb_lr, lb_dps->nb_lr_map, > - ods_size(lr_datapaths), false, > - NULL, lr_datapaths); > - } > - > - /* Update columns. */ > - sbrec_load_balancer_set_name(sbrec_lb, lb_dps->lb->nlb->name); > - sbrec_load_balancer_set_vips(sbrec_lb, > - ovn_northd_lb_get_vips(lb_dps->lb)); > - sbrec_load_balancer_set_protocol(sbrec_lb, lb_dps->lb->nlb->protocol); > - > - if (chassis_features->ls_dpg_column) { > - sbrec_load_balancer_set_ls_datapath_group( > - sbrec_lb, lb_dpg ? lb_dpg->dp_group : NULL > - ); > - sbrec_load_balancer_set_datapath_group(sbrec_lb, NULL); > - } else { > - /* datapath_group column is deprecated. */ > - sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, NULL); > - sbrec_load_balancer_set_datapath_group( > - sbrec_lb, lb_dpg ? lb_dpg->dp_group : NULL > - ); > - } > - > - sbrec_load_balancer_set_lr_datapath_group( > - sbrec_lb, lb_lr_dpg ? lb_lr_dpg->dp_group : NULL > - ); > - sbrec_load_balancer_set_options(sbrec_lb, &options); > - /* Clearing 'datapaths' column, since 'dp_group' is in use. */ > - sbrec_load_balancer_set_datapaths(sbrec_lb, NULL, 0); > - smap_destroy(&options); > - } > - > - struct ovn_dp_group *dpg; > - HMAP_FOR_EACH_POP (dpg, node, &ls_dp_groups) { > - bitmap_free(dpg->bitmap); > - free(dpg); > - } > - hmap_destroy(&ls_dp_groups); > - > - HMAP_FOR_EACH_POP (dpg, node, &lr_dp_groups) { > - bitmap_free(dpg->bitmap); > - free(dpg); > - } > - hmap_destroy(&lr_dp_groups); > - > - struct sb_lb *sb_lb; > - HMAP_FOR_EACH_POP (sb_lb, hmap_node, &sb_lbs) { > - free(sb_lb); > - } > - hmap_destroy(&sb_lbs); > - > - /* Datapath_Binding.load_balancers is not used anymore, it's still in the > - * schema for compatibility reasons. Reset it to empty, just in case. > - */ > - struct ovn_datapath *od; > - HMAP_FOR_EACH (od, key_node, &ls_datapaths->datapaths) { > - ovs_assert(od->nbs); > - > - if (od->sb->n_load_balancers) { > - sbrec_datapath_binding_set_load_balancers(od->sb, NULL, 0); > - } > - } > - HMAP_FOR_EACH (od, key_node, &lr_datapaths->datapaths) { > - ovs_assert(od->nbr); > - > - if (od->sb->n_load_balancers) { > - sbrec_datapath_binding_set_load_balancers(od->sb, NULL, 0); > - } > - } > -} > - > -bool > -check_sb_lb_duplicates(const struct sbrec_load_balancer_table *table) > -{ > - struct sset existing_nb_lb_uuids = > - SSET_INITIALIZER(&existing_nb_lb_uuids); > - const struct sbrec_load_balancer *sbrec_lb; > - bool duplicates = false; > - > - SBREC_LOAD_BALANCER_TABLE_FOR_EACH (sbrec_lb, table) { > - const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); > - if (nb_lb_uuid && !sset_add(&existing_nb_lb_uuids, nb_lb_uuid)) { > - duplicates = true; > - break; > - } > - } > - > - sset_destroy(&existing_nb_lb_uuids); > - return duplicates; > -} > - > /* Syncs the SB port binding for the ovn_port 'op' of a logical switch port. > * Caller should make sure that the OVN SB IDL txn is not NULL. Presently it > * only syncs the nat column of port binding corresponding to the 'op->nbsp' */ > diff --git a/northd/northd.h b/northd/northd.h > index 297b1a65b9..579edb8bdf 100644 > --- a/northd/northd.h > +++ b/northd/northd.h > @@ -715,12 +715,6 @@ 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 *, > - struct ovn_datapaths *ls_datapaths, > - struct ovn_datapaths *lr_datapaths, > - struct hmap *lbs, > - struct chassis_features *chassis_features); > -bool check_sb_lb_duplicates(const struct sbrec_load_balancer_table *); > > struct lr_stateful_table; > void sync_pbs(struct ovsdb_idl_txn *, struct hmap *ls_ports, > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index 263eb343eb..5c33a8a6c2 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -2938,6 +2938,8 @@ sw1_sb_uuid=$(fetch_column datapath_binding _uuid external_ids:name=sw1) > echo "$sw0_sb_uuid" > sw_sb_uuids > echo "$sw1_sb_uuid" >> sw_sb_uuids > > +lb0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lb0) > + > echo > echo "__file__:__line__: Check that SB lb0 has sw0 and sw1 in datapaths column." > AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl > @@ -2945,6 +2947,8 @@ AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Gr > $(cat sw_sb_uuids | sort) > ]) > > +lbg0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg0) > + > echo > echo "__file__:__line__: Check that SB lbg0 has sw0 and sw1 in datapaths column." > AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl > @@ -3014,6 +3018,64 @@ echo "__file__:__line__: Set hairpin_snat_ip on lb1 and check that SB DB is upda > check ovn-nbctl --wait=sb set Load_Balancer lb1 options:hairpin_snat_ip="42.42.42.42 4242::4242" > check_column "$lb1_uuid" sb:load_balancer _uuid name=lb1 options='{hairpin_orig_tuple="true", hairpin_snat_ip="42.42.42.42 4242::4242"}' > > +echo > +echo "__file__:__line__: Set option:bar=foo on lbg1 and check that sync_to_sb_lb engine node didn't recompute." > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-nbctl --wait=sb set load_balancer lbg1 options:bar=foo > +check_engine_stats sync_to_sb_lb norecompute compute > + > +# Manually clear the sb:load_balancer.ls_datapath_group column for > +# all load balancers and check that it is resynced back when the > +# NB lbg1 is modified. > + > +echo > +echo "__file__:__line__: Clear the ls_datapath_group column of all the SB load balancers." > + > +for l in $(ovn-sbctl --bare --columns _uuid list load_balancer) > +do > + check ovn-sbctl clear load_balancer $l ls_datapath_group > +done > + > +lbg1_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg1) > +AT_CHECK([test "$lbg1_dp_group" = ""]) > + > +echo > +echo "__file__:__line__: Set option:foo=bar on lbg1 and check that sync_to_sb_lb engine node recomputed." > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-nbctl --wait=sb set load_balancer lbg1 options:foo=bar > +check_engine_stats sync_to_sb_lb recompute compute > + > +# Manually clear the sb:load_balancer.lr_datapath_group column for > +# all load balancers and check that it is resynced back when the > +# NB lbg1 is modified. > + > +echo > +echo "__file__:__line__: Clear the lr_datapath_group column of all the SB load balancers." > + > +for l in $(ovn-sbctl --bare --columns _uuid list load_balancer) > +do > + check ovn-sbctl clear load_balancer $l lr_datapath_group > +done > + > +echo > +echo "__file__:__line__: Set option:foo=foo on lbg1 and check that sync_to_sb_lb engine node recomputed." > + > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > +check ovn-nbctl --wait=sb set load_balancer lbg1 options:foo=foo > +check_engine_stats sync_to_sb_lb recompute compute > + > +lbg1_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg1) > + > +echo > +echo "__file__:__line__: Check that SB lbg1 has sw0 and sw1 in datapaths column." > + > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl > + | grep -A1 $lbg1_dp_group | tail -1 | tr ' ' '\n' | sort], [0], [dnl > +$(cat sw_sb_uuids | sort) > +]) > + > echo > echo "__file__:__line__: Delete load balancers lb1 and lbg1 and check that datapath sw1's load_balancers is still empty." > > @@ -3024,6 +3086,8 @@ echo > echo "__file__:__line__: Delete switch sw0." > check ovn-nbctl --wait=sb ls-del sw0 > > +lb0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lb0) > + > echo > echo "__file__:__line__: Check that SB lb0 has only sw1 in datapaths column." > AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl > @@ -3031,6 +3095,8 @@ AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Gr > $sw1_sb_uuid > ]) > > +lbg0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg0) > + > echo > echo "__file__:__line__: Check that SB lbg0 has only sw1 in datapaths column." > AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl > @@ -10521,8 +10587,7 @@ check ovn-nbctl --wait=sb lb-add lb1 10.0.0.10:80 10.0.0.3:80 > check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > - > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > @@ -10531,7 +10596,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10541,7 +10606,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > @@ -10550,7 +10615,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > > CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10560,7 +10625,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > > CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10618,7 +10683,7 @@ check_engine_stats lr_stateful norecompute compute > # A LB applied to a switch/router triggers: > # - a recompute in the first iteration (handling northd change) > # - a compute in the second iteration (handling SB update) > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE((1)) > @@ -10631,7 +10696,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) > > # Cleanup the vip of lb1. > @@ -10642,7 +10707,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) > > # Set the vips of lb1 back > @@ -10653,7 +10718,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) > > # Add another vip to lb1 > @@ -10664,7 +10729,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) > > # Disassociate lb1 from sw0. There should be a full recompute of northd engine node. > @@ -10687,7 +10752,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > > CHECK_NO_CHANGE_AFTER_RECOMPUTE > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10708,7 +10773,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Modify the backend of the lb1 vip > @@ -10718,7 +10783,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Cleanup the vip of lb1. > @@ -10728,7 +10793,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Set the vips of lb1 back > @@ -10738,7 +10803,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Add another vip to lb1 > @@ -10748,7 +10813,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10779,7 +10844,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10796,7 +10861,7 @@ check ovn-nbctl --wait=sb add load_balancer_group . load_Balancer $lb1_uuid > check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10806,7 +10871,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > > # Update lb and this should not result in northd recompute > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10816,7 +10881,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > > # Modify the backend of the lb1 vip > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10826,7 +10891,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Cleanup the vip of lb1. > @@ -10837,7 +10902,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Set the vips of lb1 back > @@ -10848,7 +10913,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Add another vip to lb1 > @@ -10859,7 +10924,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10875,7 +10940,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Modify the backend of the lb1 vip > @@ -10885,7 +10950,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Cleanup the vip of lb1. > @@ -10895,7 +10960,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Set the vips of lb1 back > @@ -10905,7 +10970,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Add another vip to lb1 > @@ -10915,7 +10980,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10935,7 +11000,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10979,7 +11044,7 @@ check_engine_stats northd norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10989,7 +11054,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -10998,7 +11063,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -11008,7 +11073,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -11018,7 +11083,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -11028,7 +11093,7 @@ check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -11059,7 +11124,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Deleting lb2 should result in lflow recompute as it is > @@ -11071,7 +11136,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats ls_stateful norecompute compute > check_engine_stats lflow norecompute compute > -check_engine_stats sync_to_sb_lb recompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -11281,6 +11346,7 @@ check ovn-nbctl --wait=sb ls-lb-add sw0 lb1 > check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lflow norecompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Clear the VIPs of lb1 > @@ -11289,6 +11355,7 @@ check ovn-nbctl --wait=sb clear load_balancer . vips > check_engine_stats lb_data norecompute compute > check_engine_stats northd norecompute compute > check_engine_stats lflow norecompute compute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > @@ -11296,6 +11363,7 @@ check ovn-nbctl --wait=sb lb-del lb1 > check_engine_stats lb_data norecompute compute > check_engine_stats northd recompute nocompute > check_engine_stats lflow recompute nocompute > +check_engine_stats sync_to_sb_lb recompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > AT_CLEANUP > @@ -11544,6 +11612,7 @@ check_engine_stats northd recompute nocompute > check_engine_stats lr_nat recompute nocompute > check_engine_stats lr_stateful recompute nocompute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb recompute nocompute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11557,6 +11626,7 @@ check_engine_stats northd recompute compute > check_engine_stats lr_nat recompute nocompute > check_engine_stats lr_stateful recompute nocompute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb recompute nocompute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11569,6 +11639,7 @@ check_engine_stats northd recompute compute > check_engine_stats lr_nat recompute nocompute > check_engine_stats lr_stateful recompute nocompute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb recompute nocompute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11595,6 +11666,7 @@ check_engine_stats northd recompute nocompute > check_engine_stats lr_nat recompute nocompute > check_engine_stats lr_stateful recompute nocompute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb recompute nocompute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11607,6 +11679,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_nat norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Update the NAT options column > @@ -11616,6 +11689,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_nat norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Update the NAT external_ip column > @@ -11626,6 +11700,7 @@ check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Update the NAT logical_ip column > @@ -11636,6 +11711,7 @@ check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Update the NAT type > @@ -11646,6 +11722,7 @@ check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Create a dnat_and_snat NAT with external_mac and logical_port > @@ -11656,6 +11733,7 @@ check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > nat2_uuid=$(ovn-nbctl --bare --columns _uuid find nat logical_ip=10.0.0.4) > @@ -11667,6 +11745,7 @@ check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Create a load balancer and add the lb vip as NAT > @@ -11683,6 +11762,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11694,6 +11774,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11705,6 +11786,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11716,6 +11798,7 @@ check_engine_stats northd norecompute compute > check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11727,6 +11810,7 @@ check_engine_stats lr_nat norecompute compute > check_engine_stats lr_stateful norecompute compute > check_engine_stats lflow norecompute compute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb norecompute compute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > # Create router Policy > @@ -11736,6 +11820,7 @@ check_engine_stats northd recompute nocompute > check_engine_stats lr_nat recompute nocompute > check_engine_stats lr_stateful recompute nocompute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb recompute nocompute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > @@ -11745,6 +11830,7 @@ check_engine_stats northd recompute nocompute > check_engine_stats lr_nat recompute nocompute > check_engine_stats lr_stateful recompute nocompute > check_engine_stats sync_to_sb_pb recompute nocompute > +check_engine_stats sync_to_sb_lb recompute nocompute > check_engine_stats lflow recompute nocompute > CHECK_NO_CHANGE_AFTER_RECOMPUTE >
diff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c index d39cbbf2e6..80f3621bb9 100644 --- a/northd/en-sync-sb.c +++ b/northd/en-sync-sb.c @@ -18,17 +18,21 @@ #include <stdlib.h> #include <stdio.h> +/* OVS includes. */ #include "lib/svec.h" #include "openvswitch/util.h" +/* OVN includes. */ #include "en-lr-nat.h" #include "en-lr-stateful.h" #include "en-sync-sb.h" +#include "lb.h" #include "lib/inc-proc-eng.h" #include "lib/lb.h" #include "lib/ovn-nb-idl.h" #include "lib/ovn-sb-idl.h" #include "lib/ovn-util.h" +#include "lflow-mgr.h" #include "northd.h" #include "openvswitch/vlog.h" @@ -51,6 +55,40 @@ static void build_port_group_address_set(const struct nbrec_port_group *, struct svec *ipv4_addrs, struct svec *ipv6_addrs); +struct sb_lb_table; +struct sb_lb_record; +static void sb_lb_table_init(struct sb_lb_table *); +static void sb_lb_table_clear(struct sb_lb_table *); +static void sb_lb_table_destroy(struct sb_lb_table *); + +static struct sb_lb_record *sb_lb_table_find(struct hmap *sb_lbs, + const struct uuid *); +static void sb_lb_table_build_and_sync(struct sb_lb_table *, + struct ovsdb_idl_txn *ovnsb_txn, + const struct sbrec_load_balancer_table *, + const struct sbrec_logical_dp_group_table *, + struct hmap *lb_dps_map, + struct ovn_datapaths *ls_datapaths, + struct ovn_datapaths *lr_datapaths, + struct chassis_features *); +static bool sync_sb_lb_record(struct sb_lb_record *, + const struct sbrec_load_balancer *, + const struct sbrec_logical_dp_group_table *, + struct sb_lb_table *, + struct ovsdb_idl_txn *ovnsb_txn, + struct ovn_datapaths *ls_datapaths, + struct ovn_datapaths *lr_datapaths, + struct chassis_features *); +static bool sync_changed_lbs(struct sb_lb_table *, + struct ovsdb_idl_txn *ovnsb_txn, + const struct sbrec_load_balancer_table *, + const struct sbrec_logical_dp_group_table *, + struct tracked_lbs *, + struct ovn_datapaths *ls_datapaths, + struct ovn_datapaths *lr_datapaths, + struct chassis_features *); +static bool check_sb_lb_duplicates(const struct sbrec_load_balancer_table *); + void * en_sync_to_sb_init(struct engine_node *node OVS_UNUSED, struct engine_arg *arg OVS_UNUSED) @@ -206,49 +244,99 @@ sync_to_sb_addr_set_nb_port_group_handler(struct engine_node *node, /* sync_to_sb_lb engine node functions. * This engine node syncs the SB load balancers. */ +struct sb_lb_record { + struct hmap_node key_node; /* Index on 'nblb->header_.uuid'. */ + + struct ovn_lb_datapaths *lb_dps; + const struct sbrec_load_balancer *sbrec_lb; + struct ovn_dp_group *ls_dpg; + struct ovn_dp_group *lr_dpg; + struct uuid sb_uuid; +}; + +struct sb_lb_table { + struct hmap entries; /* Stores struct sb_lb_record. */ + struct hmap ls_dp_groups; + struct hmap lr_dp_groups; +}; + +struct ed_type_sync_to_sb_lb_data { + struct sb_lb_table sb_lbs; +}; + void * en_sync_to_sb_lb_init(struct engine_node *node OVS_UNUSED, struct engine_arg *arg OVS_UNUSED) { - return NULL; + struct ed_type_sync_to_sb_lb_data *data = xzalloc(sizeof *data); + sb_lb_table_init(&data->sb_lbs); + + return data; } void -en_sync_to_sb_lb_run(struct engine_node *node, void *data OVS_UNUSED) +en_sync_to_sb_lb_run(struct engine_node *node, void *data_) { + struct northd_data *northd_data = engine_get_input_data("northd", node); const struct sbrec_load_balancer_table *sb_load_balancer_table = EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); + const struct sbrec_logical_dp_group_table *sb_dpgrp_table = + EN_OVSDB_GET(engine_get_input("SB_logical_dp_group", node)); const struct engine_context *eng_ctx = engine_get_context(); - struct northd_data *northd_data = engine_get_input_data("northd", node); + struct ed_type_sync_to_sb_lb_data *data = data_; + + sb_lb_table_clear(&data->sb_lbs); + sb_lb_table_build_and_sync(&data->sb_lbs, eng_ctx->ovnsb_idl_txn, + sb_load_balancer_table, + sb_dpgrp_table, + &northd_data->lb_datapaths_map, + &northd_data->ls_datapaths, + &northd_data->lr_datapaths, + &northd_data->features); - 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); engine_set_node_state(node, EN_UPDATED); } void -en_sync_to_sb_lb_cleanup(void *data OVS_UNUSED) +en_sync_to_sb_lb_cleanup(void *data_) { - + struct ed_type_sync_to_sb_lb_data *data = data_; + sb_lb_table_destroy(&data->sb_lbs); } bool -sync_to_sb_lb_northd_handler(struct engine_node *node, void *data OVS_UNUSED) +sync_to_sb_lb_northd_handler(struct engine_node *node, void *data_) { struct northd_data *nd = engine_get_input_data("northd", node); - if (!northd_has_tracked_data(&nd->trk_data) || - northd_has_lbs_in_tracked_data(&nd->trk_data)) { - /* Return false if no tracking data or if lbs changed. */ + if (!northd_has_tracked_data(&nd->trk_data)) { + /* Return false if no tracking data. */ return false; } + if (!northd_has_lbs_in_tracked_data(&nd->trk_data)) { + return true; + } - /* There are only NB LSP related changes and these can be safely - * ignore and returned true. However in case the northd engine - * tracking data includes other changes, we need to do additional - * checks before safely ignoring. */ + const struct engine_context *eng_ctx = engine_get_context(); + if (!eng_ctx->ovnsb_idl_txn) { + return false; + } + + const struct sbrec_logical_dp_group_table *sb_dpgrp_table = + EN_OVSDB_GET(engine_get_input("SB_logical_dp_group", node)); + const struct sbrec_load_balancer_table *sb_lb_table = + EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); + struct ed_type_sync_to_sb_lb_data *data = data_; + + if (!sync_changed_lbs(&data->sb_lbs, eng_ctx->ovnsb_idl_txn, sb_lb_table, + sb_dpgrp_table, &nd->trk_data.trk_lbs, + &nd->ls_datapaths, &nd->lr_datapaths, + &nd->features)) { + return false; + } + + engine_set_node_state(node, EN_UPDATED); return true; } @@ -519,3 +607,388 @@ sb_address_set_lookup_by_name(struct ovsdb_idl_index *sbrec_addr_set_by_name, return retval; } + +/* static functions related to sync_to_sb_lb */ + +static void +sb_lb_table_init(struct sb_lb_table *sb_lbs) +{ + hmap_init(&sb_lbs->entries); + ovn_dp_groups_init(&sb_lbs->ls_dp_groups); + ovn_dp_groups_init(&sb_lbs->lr_dp_groups); +} + +static void +sb_lb_table_clear(struct sb_lb_table *sb_lbs) +{ + struct sb_lb_record *sb_lb; + HMAP_FOR_EACH_POP (sb_lb, key_node, &sb_lbs->entries) { + free(sb_lb); + } + + ovn_dp_groups_clear(&sb_lbs->ls_dp_groups); + ovn_dp_groups_clear(&sb_lbs->lr_dp_groups); +} + +static void +sb_lb_table_destroy(struct sb_lb_table *sb_lbs) +{ + sb_lb_table_clear(sb_lbs); + hmap_destroy(&sb_lbs->entries); + ovn_dp_groups_destroy(&sb_lbs->ls_dp_groups); + ovn_dp_groups_destroy(&sb_lbs->lr_dp_groups); +} + +static struct sb_lb_record * +sb_lb_table_find(struct hmap *sb_lbs, const struct uuid *lb_uuid) +{ + struct sb_lb_record *sb_lb; + HMAP_FOR_EACH_WITH_HASH (sb_lb, key_node, uuid_hash(lb_uuid), + sb_lbs) { + if (uuid_equals(&sb_lb->lb_dps->lb->nlb->header_.uuid, lb_uuid)) { + return sb_lb; + } + } + + return NULL; +} + +static void +sb_lb_table_build_and_sync(struct sb_lb_table *sb_lbs, + struct ovsdb_idl_txn *ovnsb_txn, + const struct sbrec_load_balancer_table *sb_lb_table, + const struct sbrec_logical_dp_group_table *sb_dpgrp_table, + struct hmap *lb_dps_map, + struct ovn_datapaths *ls_datapaths, + struct ovn_datapaths *lr_datapaths, + struct chassis_features *chassis_features) +{ + struct hmap tmp_sb_lbs = HMAP_INITIALIZER(&tmp_sb_lbs); + struct ovn_lb_datapaths *lb_dps; + struct sb_lb_record *sb_lb; + + HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) { + if (!lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { + continue; + } + + sb_lb = xzalloc(sizeof *sb_lb); + sb_lb->lb_dps = lb_dps; + hmap_insert(&tmp_sb_lbs, &sb_lb->key_node, + uuid_hash(&lb_dps->lb->nlb->header_.uuid)); + } + + const struct sbrec_load_balancer *sbrec_lb; + SBREC_LOAD_BALANCER_TABLE_FOR_EACH_SAFE (sbrec_lb, + sb_lb_table) { + const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); + struct uuid lb_uuid; + if (!nb_lb_uuid || !uuid_from_string(&lb_uuid, nb_lb_uuid)) { + sbrec_load_balancer_delete(sbrec_lb); + continue; + } + + sb_lb = sb_lb_table_find(&tmp_sb_lbs, &lb_uuid); + if (sb_lb) { + sb_lb->sbrec_lb = sbrec_lb; + bool success = sync_sb_lb_record(sb_lb, sbrec_lb, sb_dpgrp_table, + sb_lbs, ovnsb_txn, ls_datapaths, + lr_datapaths, chassis_features); + /* Since we are rebuilding and syncing, sync_sb_lb_record should + * not return false. */ + ovs_assert(success); + + hmap_remove(&tmp_sb_lbs, &sb_lb->key_node); + hmap_insert(&sb_lbs->entries, &sb_lb->key_node, + uuid_hash(&sb_lb->lb_dps->lb->nlb->header_.uuid)); + } else { + sbrec_load_balancer_delete(sbrec_lb); + } + } + + HMAP_FOR_EACH_POP (sb_lb, key_node, &tmp_sb_lbs) { + bool success = sync_sb_lb_record(sb_lb, NULL, sb_dpgrp_table, sb_lbs, + ovnsb_txn, ls_datapaths, lr_datapaths, + chassis_features); + /* Since we are rebuilding and syncing, sync_sb_lb_record should not + * return false. */ + ovs_assert(success); + + hmap_insert(&sb_lbs->entries, &sb_lb->key_node, + uuid_hash(&sb_lb->lb_dps->lb->nlb->header_.uuid)); + } + + hmap_destroy(&tmp_sb_lbs); +} + +static bool +sync_sb_lb_record(struct sb_lb_record *sb_lb, + const struct sbrec_load_balancer *sbrec_lb, + const struct sbrec_logical_dp_group_table *sb_dpgrp_table, + struct sb_lb_table *sb_lbs, + struct ovsdb_idl_txn *ovnsb_txn, + struct ovn_datapaths *ls_datapaths, + struct ovn_datapaths *lr_datapaths, + struct chassis_features *chassis_features) +{ + struct sbrec_logical_dp_group *sbrec_ls_dp_group = NULL; + struct sbrec_logical_dp_group *sbrec_lr_dp_group = NULL; + const struct ovn_lb_datapaths *lb_dps; + struct ovn_dp_group *pre_sync_ls_dpg; + struct ovn_dp_group *pre_sync_lr_dpg; + + lb_dps = sb_lb->lb_dps; + pre_sync_ls_dpg = sb_lb->ls_dpg; + pre_sync_lr_dpg = sb_lb->lr_dpg; + + if (!sbrec_lb) { + sb_lb->sb_uuid = uuid_random(); + sbrec_lb = sbrec_load_balancer_insert_persist_uuid(ovnsb_txn, + &sb_lb->sb_uuid); + char *lb_id = xasprintf( + UUID_FMT, UUID_ARGS(&lb_dps->lb->nlb->header_.uuid)); + const struct smap external_ids = + SMAP_CONST1(&external_ids, "lb_id", lb_id); + sbrec_load_balancer_set_external_ids(sbrec_lb, &external_ids); + free(lb_id); + } else { + sb_lb->sb_uuid = sbrec_lb->header_.uuid; + sbrec_ls_dp_group = + chassis_features->ls_dpg_column + ? sbrec_lb->ls_datapath_group + : sbrec_lb->datapath_group; /* deprecated */ + + sbrec_lr_dp_group = sbrec_lb->lr_datapath_group; + } + + if (lb_dps->n_nb_ls) { + sb_lb->ls_dpg = ovn_dp_group_get(&sb_lbs->ls_dp_groups, + lb_dps->n_nb_ls, + lb_dps->nb_ls_map, + ods_size(ls_datapaths)); + if (sb_lb->ls_dpg) { + /* Update the dpg's sb dp_group. */ + sb_lb->ls_dpg->dp_group = + sbrec_logical_dp_group_table_get_for_uuid(sb_dpgrp_table, + &sb_lb->ls_dpg->dpg_uuid); + if (!sb_lb->ls_dpg->dp_group) { + /* Ideally this should not happen. But it can still happen + * due to 2 reasons: + * 1. There is a bug in the dp_group management. We should + * perhaps assert here. + * 2. A User or CMS may delete the logical_dp_groups in SB DB + * or clear the SB:Load_balancer.ls_datapath_group column + * (intentionally or accidentally) + * + * Because of (2) it is better to return false instead of + * assert,so that we recover from th inconsistent SB DB. + */ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_WARN_RL(&rl, "SB Load balancer [%s]'s ls_dp_group column " + "is not set (which is unexpected). It should " + "have been referencing the dp group ["UUID_FMT"]", + sb_lb->lb_dps->lb->nlb->name, + UUID_ARGS(&sb_lb->ls_dpg->dpg_uuid)); + return false; + } + } else { + sb_lb->ls_dpg = ovn_dp_group_create( + ovnsb_txn, &sb_lbs->ls_dp_groups, sbrec_ls_dp_group, + lb_dps->n_nb_ls, lb_dps->nb_ls_map, + ods_size(ls_datapaths), true, + ls_datapaths, lr_datapaths); + } + + if (chassis_features->ls_dpg_column) { + sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, + sb_lb->ls_dpg->dp_group); + sbrec_load_balancer_set_datapath_group(sbrec_lb, NULL); + } else { + /* datapath_group column is deprecated. */ + sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, NULL); + sbrec_load_balancer_set_datapath_group(sbrec_lb, + sb_lb->ls_dpg->dp_group); + + } + } else { + sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, NULL); + sbrec_load_balancer_set_datapath_group(sbrec_lb, NULL); + } + + + if (lb_dps->n_nb_lr) { + sb_lb->lr_dpg = ovn_dp_group_get(&sb_lbs->lr_dp_groups, + lb_dps->n_nb_lr, + lb_dps->nb_lr_map, + ods_size(lr_datapaths)); + if (sb_lb->lr_dpg) { + /* Update the dpg's sb dp_group. */ + sb_lb->lr_dpg->dp_group = + sbrec_logical_dp_group_table_get_for_uuid(sb_dpgrp_table, + &sb_lb->lr_dpg->dpg_uuid); + if (!sb_lb->lr_dpg->dp_group) { + /* Ideally this should not happen. But it can still happen + * due to 2 reasons: + * 1. There is a bug in the dp_group management. We should + * perhaps assert here. + * 2. A User or CMS may delete the logical_dp_groups in SB DB + * or clear the SB:Load_balancer.lr_datapath_group column + * (intentionally or accidentally) + * + * Because of (2) it is better to return false instead of + * assert,so that we recover from th inconsistent SB DB. + */ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_WARN_RL(&rl, "SB Load balancer [%s]'s lr_dp_group column " + "is not set (which is unexpected). It should " + "have been referencing the dp group ["UUID_FMT"]", + sb_lb->lb_dps->lb->nlb->name, + UUID_ARGS(&sb_lb->lr_dpg->dpg_uuid)); + return false; + } + } else { + sb_lb->lr_dpg = ovn_dp_group_create( + ovnsb_txn, &sb_lbs->lr_dp_groups, sbrec_lr_dp_group, + lb_dps->n_nb_lr, lb_dps->nb_lr_map, + ods_size(lr_datapaths), false, + ls_datapaths, lr_datapaths); + } + + sbrec_load_balancer_set_lr_datapath_group(sbrec_lb, + sb_lb->lr_dpg->dp_group); + } else { + sbrec_load_balancer_set_lr_datapath_group(sbrec_lb, NULL); + } + + if (pre_sync_ls_dpg != sb_lb->ls_dpg) { + if (sb_lb->ls_dpg) { + inc_ovn_dp_group_ref(sb_lb->ls_dpg); + } + if (pre_sync_ls_dpg) { + dec_ovn_dp_group_ref(&sb_lbs->ls_dp_groups, pre_sync_ls_dpg); + } + } + + if (pre_sync_lr_dpg != sb_lb->lr_dpg) { + if (sb_lb->lr_dpg) { + inc_ovn_dp_group_ref(sb_lb->lr_dpg); + } + if (pre_sync_lr_dpg) { + dec_ovn_dp_group_ref(&sb_lbs->lr_dp_groups, pre_sync_lr_dpg); + } + } + + /* Update columns. */ + sbrec_load_balancer_set_name(sbrec_lb, lb_dps->lb->nlb->name); + sbrec_load_balancer_set_vips(sbrec_lb, + ovn_northd_lb_get_vips(lb_dps->lb)); + sbrec_load_balancer_set_protocol(sbrec_lb, lb_dps->lb->nlb->protocol); + + /* Store the fact that northd provides the original (destination IP + + * transport port) tuple. + */ + struct smap options; + smap_clone(&options, &lb_dps->lb->nlb->options); + smap_replace(&options, "hairpin_orig_tuple", "true"); + sbrec_load_balancer_set_options(sbrec_lb, &options); + /* Clearing 'datapaths' column, since 'dp_group' is in use. */ + sbrec_load_balancer_set_datapaths(sbrec_lb, NULL, 0); + smap_destroy(&options); + + return true; +} + +static bool +sync_changed_lbs(struct sb_lb_table *sb_lbs, + struct ovsdb_idl_txn *ovnsb_txn, + const struct sbrec_load_balancer_table *sb_lb_table, + const struct sbrec_logical_dp_group_table *sb_dpgrp_table, + struct tracked_lbs *trk_lbs, + struct ovn_datapaths *ls_datapaths, + struct ovn_datapaths *lr_datapaths, + struct chassis_features *chassis_features) +{ + struct ovn_lb_datapaths *lb_dps; + struct hmapx_node *hmapx_node; + struct sb_lb_record *sb_lb; + + HMAPX_FOR_EACH (hmapx_node, &trk_lbs->deleted) { + lb_dps = hmapx_node->data; + + sb_lb = sb_lb_table_find(&sb_lbs->entries, + &lb_dps->lb->nlb->header_.uuid); + if (sb_lb) { + const struct sbrec_load_balancer *sbrec_lb = + sbrec_load_balancer_table_get_for_uuid(sb_lb_table, + &sb_lb->sb_uuid); + if (sbrec_lb) { + sbrec_load_balancer_delete(sbrec_lb); + } + + hmap_remove(&sb_lbs->entries, &sb_lb->key_node); + free(sb_lb); + } + } + + HMAPX_FOR_EACH (hmapx_node, &trk_lbs->crupdated) { + lb_dps = hmapx_node->data; + + sb_lb = sb_lb_table_find(&sb_lbs->entries, + &lb_dps->lb->nlb->header_.uuid); + + if (!sb_lb && !lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { + continue; + } + + if (!sb_lb) { + sb_lb = xzalloc(sizeof *sb_lb); + sb_lb->lb_dps = lb_dps; + hmap_insert(&sb_lbs->entries, &sb_lb->key_node, + uuid_hash(&lb_dps->lb->nlb->header_.uuid)); + } else { + sb_lb->sbrec_lb = + sbrec_load_balancer_table_get_for_uuid(sb_lb_table, + &sb_lb->sb_uuid); + } + + if (sb_lb && !lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { + const struct sbrec_load_balancer *sbrec_lb = + sbrec_load_balancer_table_get_for_uuid(sb_lb_table, + &sb_lb->sb_uuid); + if (sbrec_lb) { + sbrec_load_balancer_delete(sbrec_lb); + } + + hmap_remove(&sb_lbs->entries, &sb_lb->key_node); + free(sb_lb); + } + + if (!sync_sb_lb_record(sb_lb, sb_lb->sbrec_lb, sb_dpgrp_table, sb_lbs, + ovnsb_txn, ls_datapaths, lr_datapaths, + chassis_features)) { + return false; + } + } + + return true; +} + +static bool +check_sb_lb_duplicates(const struct sbrec_load_balancer_table *table) +{ + struct sset existing_nb_lb_uuids = + SSET_INITIALIZER(&existing_nb_lb_uuids); + const struct sbrec_load_balancer *sbrec_lb; + bool duplicates = false; + + SBREC_LOAD_BALANCER_TABLE_FOR_EACH (sbrec_lb, table) { + const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); + if (nb_lb_uuid && !sset_add(&existing_nb_lb_uuids, nb_lb_uuid)) { + duplicates = true; + break; + } + } + + sset_destroy(&existing_nb_lb_uuids); + return duplicates; +} diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c index 40a9e5e06c..d215c7792b 100644 --- a/northd/inc-proc-northd.c +++ b/northd/inc-proc-northd.c @@ -264,6 +264,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, sync_to_sb_lb_northd_handler); engine_add_input(&en_sync_to_sb_lb, &en_sb_load_balancer, sync_to_sb_lb_sb_load_balancer); + engine_add_input(&en_sync_to_sb_lb, &en_sb_logical_dp_group, NULL); engine_add_input(&en_sync_to_sb_pb, &en_northd, sync_to_sb_pb_northd_handler); diff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c index d81b13a25c..d09dc7acb5 100644 --- a/northd/lflow-mgr.c +++ b/northd/lflow-mgr.c @@ -70,21 +70,6 @@ static struct ovs_mutex *lflow_hash_lock(const struct hmap *lflow_table, uint32_t hash); static void lflow_hash_unlock(struct ovs_mutex *hash_lock); -static struct ovn_dp_group *ovn_dp_group_get( - struct hmap *dp_groups, size_t desired_n, - const unsigned long *desired_bitmap, - size_t bitmap_len); -static struct ovn_dp_group *ovn_dp_group_create( - struct ovsdb_idl_txn *ovnsb_txn, struct hmap *dp_groups, - struct sbrec_logical_dp_group *, size_t desired_n, - const unsigned long *desired_bitmap, - size_t bitmap_len, bool is_switch, - const struct ovn_datapaths *ls_datapaths, - const struct ovn_datapaths *lr_datapaths); -static struct ovn_dp_group *ovn_dp_group_get( - struct hmap *dp_groups, size_t desired_n, - const unsigned long *desired_bitmap, - size_t bitmap_len); static struct sbrec_logical_dp_group *ovn_sb_insert_or_update_logical_dp_group( struct ovsdb_idl_txn *ovnsb_txn, struct sbrec_logical_dp_group *, @@ -564,31 +549,81 @@ lflow_table_add_lflow_default_drop(struct lflow_table *lflow_table, where, lflow_ref); } -/* Given a desired bitmap, finds a datapath group in 'dp_groups'. If it - * doesn't exist, creates a new one and adds it to 'dp_groups'. +struct ovn_dp_group * +ovn_dp_group_get(struct hmap *dp_groups, size_t desired_n, + const unsigned long *desired_bitmap, + size_t bitmap_len) +{ + uint32_t hash; + + hash = hash_int(desired_n, 0); + return ovn_dp_group_find(dp_groups, desired_bitmap, bitmap_len, hash); +} + +/* Creates a new datapath group and adds it to 'dp_groups'. * If 'sb_group' is provided, function will try to re-use this group by - * either taking it directly, or by modifying, if it's not already in use. */ + * either taking it directly, or by modifying, if it's not already in use. + * Caller should first call ovn_dp_group_get() before calling this function. */ struct ovn_dp_group * -ovn_dp_group_get_or_create(struct ovsdb_idl_txn *ovnsb_txn, - struct hmap *dp_groups, - struct sbrec_logical_dp_group *sb_group, - size_t desired_n, - const unsigned long *desired_bitmap, - size_t bitmap_len, - bool is_switch, - const struct ovn_datapaths *ls_datapaths, - const struct ovn_datapaths *lr_datapaths) +ovn_dp_group_create(struct ovsdb_idl_txn *ovnsb_txn, + struct hmap *dp_groups, + struct sbrec_logical_dp_group *sb_group, + size_t desired_n, + const unsigned long *desired_bitmap, + size_t bitmap_len, + bool is_switch, + const struct ovn_datapaths *ls_datapaths, + const struct ovn_datapaths *lr_datapaths) { struct ovn_dp_group *dpg; - dpg = ovn_dp_group_get(dp_groups, desired_n, desired_bitmap, bitmap_len); - if (dpg) { - return dpg; + bool update_dp_group = false, can_modify = false; + unsigned long *dpg_bitmap; + size_t i, n = 0; + + dpg_bitmap = sb_group ? bitmap_allocate(bitmap_len) : NULL; + for (i = 0; sb_group && i < sb_group->n_datapaths; i++) { + struct ovn_datapath *datapath_od; + + datapath_od = ovn_datapath_from_sbrec( + ls_datapaths ? &ls_datapaths->datapaths : NULL, + lr_datapaths ? &lr_datapaths->datapaths : NULL, + sb_group->datapaths[i]); + if (!datapath_od || ovn_datapath_is_stale(datapath_od)) { + break; + } + bitmap_set1(dpg_bitmap, datapath_od->index); + n++; + } + if (!sb_group || i != sb_group->n_datapaths) { + /* No group or stale group. Not going to be used. */ + update_dp_group = true; + can_modify = true; + } else if (!bitmap_equal(dpg_bitmap, desired_bitmap, bitmap_len)) { + /* The group in Sb is different. */ + update_dp_group = true; + /* We can modify existing group if it's not already in use. */ + can_modify = !ovn_dp_group_find(dp_groups, dpg_bitmap, + bitmap_len, hash_int(n, 0)); } - return ovn_dp_group_create(ovnsb_txn, dp_groups, sb_group, desired_n, - desired_bitmap, bitmap_len, is_switch, - ls_datapaths, lr_datapaths); + bitmap_free(dpg_bitmap); + + dpg = xzalloc(sizeof *dpg); + dpg->bitmap = bitmap_clone(desired_bitmap, bitmap_len); + if (!update_dp_group) { + dpg->dp_group = sb_group; + } else { + dpg->dp_group = ovn_sb_insert_or_update_logical_dp_group( + ovnsb_txn, + can_modify ? sb_group : NULL, + desired_bitmap, + is_switch ? ls_datapaths : lr_datapaths); + } + dpg->dpg_uuid = dpg->dp_group->header_.uuid; + hmap_insert(dp_groups, &dpg->node, hash_int(desired_n, 0)); + + return dpg; } void @@ -987,24 +1022,6 @@ ovn_dp_group_find(const struct hmap *dp_groups, return NULL; } -static void -inc_ovn_dp_group_ref(struct ovn_dp_group *dpg) -{ - dpg->refcnt++; -} - -static void -dec_ovn_dp_group_ref(struct hmap *dp_groups, struct ovn_dp_group *dpg) -{ - dpg->refcnt--; - - if (!dpg->refcnt) { - hmap_remove(dp_groups, &dpg->node); - free(dpg->bitmap); - free(dpg); - } -} - static struct sbrec_logical_dp_group * ovn_sb_insert_or_update_logical_dp_group( struct ovsdb_idl_txn *ovnsb_txn, @@ -1031,83 +1048,6 @@ ovn_sb_insert_or_update_logical_dp_group( return dp_group; } -static struct ovn_dp_group * -ovn_dp_group_get(struct hmap *dp_groups, size_t desired_n, - const unsigned long *desired_bitmap, - size_t bitmap_len) -{ - uint32_t hash; - - hash = hash_int(desired_n, 0); - return ovn_dp_group_find(dp_groups, desired_bitmap, bitmap_len, hash); -} - -/* Creates a new datapath group and adds it to 'dp_groups'. - * If 'sb_group' is provided, function will try to re-use this group by - * either taking it directly, or by modifying, if it's not already in use. - * Caller should first call ovn_dp_group_get() before calling this function. */ -static struct ovn_dp_group * -ovn_dp_group_create(struct ovsdb_idl_txn *ovnsb_txn, - struct hmap *dp_groups, - struct sbrec_logical_dp_group *sb_group, - size_t desired_n, - const unsigned long *desired_bitmap, - size_t bitmap_len, - bool is_switch, - const struct ovn_datapaths *ls_datapaths, - const struct ovn_datapaths *lr_datapaths) -{ - struct ovn_dp_group *dpg; - - bool update_dp_group = false, can_modify = false; - unsigned long *dpg_bitmap; - size_t i, n = 0; - - dpg_bitmap = sb_group ? bitmap_allocate(bitmap_len) : NULL; - for (i = 0; sb_group && i < sb_group->n_datapaths; i++) { - struct ovn_datapath *datapath_od; - - datapath_od = ovn_datapath_from_sbrec( - ls_datapaths ? &ls_datapaths->datapaths : NULL, - lr_datapaths ? &lr_datapaths->datapaths : NULL, - sb_group->datapaths[i]); - if (!datapath_od || ovn_datapath_is_stale(datapath_od)) { - break; - } - bitmap_set1(dpg_bitmap, datapath_od->index); - n++; - } - if (!sb_group || i != sb_group->n_datapaths) { - /* No group or stale group. Not going to be used. */ - update_dp_group = true; - can_modify = true; - } else if (!bitmap_equal(dpg_bitmap, desired_bitmap, bitmap_len)) { - /* The group in Sb is different. */ - update_dp_group = true; - /* We can modify existing group if it's not already in use. */ - can_modify = !ovn_dp_group_find(dp_groups, dpg_bitmap, - bitmap_len, hash_int(n, 0)); - } - - bitmap_free(dpg_bitmap); - - dpg = xzalloc(sizeof *dpg); - dpg->bitmap = bitmap_clone(desired_bitmap, bitmap_len); - if (!update_dp_group) { - dpg->dp_group = sb_group; - } else { - dpg->dp_group = ovn_sb_insert_or_update_logical_dp_group( - ovnsb_txn, - can_modify ? sb_group : NULL, - desired_bitmap, - is_switch ? ls_datapaths : lr_datapaths); - } - dpg->dpg_uuid = dpg->dp_group->header_.uuid; - hmap_insert(dp_groups, &dpg->node, hash_int(desired_n, 0)); - - return dpg; -} - /* Adds an OVN datapath to a datapath group of existing logical flow. * Version to use when hash bucket locking is NOT required or the corresponding * hash lock is already taken. */ diff --git a/northd/lflow-mgr.h b/northd/lflow-mgr.h index f215891b97..00554ef78a 100644 --- a/northd/lflow-mgr.h +++ b/northd/lflow-mgr.h @@ -157,7 +157,10 @@ ovn_dp_groups_init(struct hmap *dp_groups) void ovn_dp_groups_clear(struct hmap *dp_groups); void ovn_dp_groups_destroy(struct hmap *dp_groups); -struct ovn_dp_group *ovn_dp_group_get_or_create( +struct ovn_dp_group *ovn_dp_group_get(struct hmap *dp_groups, size_t desired_n, + const unsigned long *desired_bitmap, + size_t bitmap_len); +struct ovn_dp_group *ovn_dp_group_create( struct ovsdb_idl_txn *ovnsb_txn, struct hmap *dp_groups, struct sbrec_logical_dp_group *sb_group, size_t desired_n, const unsigned long *desired_bitmap, @@ -165,4 +168,22 @@ struct ovn_dp_group *ovn_dp_group_get_or_create( const struct ovn_datapaths *ls_datapaths, const struct ovn_datapaths *lr_datapaths); +static inline void +inc_ovn_dp_group_ref(struct ovn_dp_group *dpg) +{ + dpg->refcnt++; +} + +static inline void +dec_ovn_dp_group_ref(struct hmap *dp_groups, struct ovn_dp_group *dpg) +{ + dpg->refcnt--; + + if (!dpg->refcnt) { + hmap_remove(dp_groups, &dpg->node); + free(dpg->bitmap); + free(dpg); + } +} + #endif /* LFLOW_MGR_H */ \ No newline at end of file diff --git a/northd/northd.c b/northd/northd.c index 96a5b52127..d21a070fdd 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -3745,244 +3745,6 @@ build_lb_port_related_data( build_lswitch_lbs_from_lrouter(lr_datapaths, lb_dps_map, lb_group_dps_map); } -struct sb_lb { - struct hmap_node hmap_node; - - const struct sbrec_load_balancer *slb; - struct ovn_dp_group *dpg; - struct ovn_dp_group *lr_dpg; - struct uuid lb_uuid; -}; - -static struct sb_lb * -find_slb_in_sb_lbs(struct hmap *sb_lbs, const struct uuid *lb_uuid) -{ - struct sb_lb *sb_lb; - HMAP_FOR_EACH_WITH_HASH (sb_lb, hmap_node, uuid_hash(lb_uuid), sb_lbs) { - if (uuid_equals(&sb_lb->lb_uuid, lb_uuid)) { - return sb_lb; - } - } - - return NULL; -} - -/* Syncs relevant load balancers (applied to logical switches) to the - * Southbound database. - */ -void -sync_lbs(struct ovsdb_idl_txn *ovnsb_txn, - const struct sbrec_load_balancer_table *sbrec_load_balancer_table, - struct ovn_datapaths *ls_datapaths, - struct ovn_datapaths *lr_datapaths, - struct hmap *lb_dps_map, - struct chassis_features *chassis_features) -{ - struct hmap ls_dp_groups = HMAP_INITIALIZER(&ls_dp_groups); - struct hmap lr_dp_groups = HMAP_INITIALIZER(&lr_dp_groups); - struct ovn_lb_datapaths *lb_dps; - struct hmap sb_lbs = HMAP_INITIALIZER(&sb_lbs); - - /* Delete any stale SB load balancer rows and create datapath - * groups for existing ones. */ - struct hmapx existing_lbs = HMAPX_INITIALIZER(&existing_lbs); - const struct sbrec_load_balancer *sbrec_lb; - SBREC_LOAD_BALANCER_TABLE_FOR_EACH_SAFE (sbrec_lb, - sbrec_load_balancer_table) { - const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); - struct uuid lb_uuid; - if (!nb_lb_uuid || !uuid_from_string(&lb_uuid, nb_lb_uuid)) { - sbrec_load_balancer_delete(sbrec_lb); - continue; - } - - /* Delete any SB load balancer entries that refer to NB load balancers - * that don't exist anymore or are not applied to switches/routers - * anymore. - * - * There is also a special case in which duplicate LBs might be created - * in the SB, e.g., due to the fact that OVSDB only ensures - * "at-least-once" consistency for clustered database tables that - * are not indexed in any way. - */ - lb_dps = ovn_lb_datapaths_find(lb_dps_map, &lb_uuid); - if (!lb_dps || (!lb_dps->n_nb_ls && !lb_dps->n_nb_lr) || - !hmapx_add(&existing_lbs, lb_dps)) { - sbrec_load_balancer_delete(sbrec_lb); - continue; - } - - struct sb_lb *sb_lb = xzalloc(sizeof *sb_lb); - sb_lb->lb_uuid = lb_uuid; - sb_lb->slb = sbrec_lb; - hmap_insert(&sb_lbs, &sb_lb->hmap_node, uuid_hash(&lb_uuid)); - - /* Find or create datapath group for this load balancer. */ - if (lb_dps->n_nb_ls) { - struct sbrec_logical_dp_group *ls_datapath_group - = chassis_features->ls_dpg_column - ? sb_lb->slb->ls_datapath_group - : sb_lb->slb->datapath_group; /* deprecated */ - sb_lb->dpg = ovn_dp_group_get_or_create( - ovnsb_txn, &ls_dp_groups, - ls_datapath_group, - lb_dps->n_nb_ls, lb_dps->nb_ls_map, - ods_size(ls_datapaths), true, - ls_datapaths, NULL); - } - if (lb_dps->n_nb_lr) { - sb_lb->lr_dpg = ovn_dp_group_get_or_create( - ovnsb_txn, &lr_dp_groups, - sb_lb->slb->lr_datapath_group, - lb_dps->n_nb_lr, lb_dps->nb_lr_map, - ods_size(lr_datapaths), false, - NULL, lr_datapaths); - } - } - hmapx_destroy(&existing_lbs); - - /* Create SB Load balancer records if not present and sync - * the SB load balancer columns. */ - HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) { - - if (!lb_dps->n_nb_ls && !lb_dps->n_nb_lr) { - continue; - } - - /* Store the fact that northd provides the original (destination IP + - * transport port) tuple. - */ - struct smap options; - smap_clone(&options, &lb_dps->lb->nlb->options); - smap_replace(&options, "hairpin_orig_tuple", "true"); - - struct sb_lb *sb_lb = find_slb_in_sb_lbs(&sb_lbs, - &lb_dps->lb->nlb->header_.uuid); - ovs_assert(!sb_lb || (sb_lb->slb && (sb_lb->dpg || sb_lb->lr_dpg))); - struct ovn_dp_group *lb_dpg = NULL, *lb_lr_dpg = NULL; - if (!sb_lb) { - sbrec_lb = sbrec_load_balancer_insert(ovnsb_txn); - char *lb_id = xasprintf( - UUID_FMT, UUID_ARGS(&lb_dps->lb->nlb->header_.uuid)); - const struct smap external_ids = - SMAP_CONST1(&external_ids, "lb_id", lb_id); - sbrec_load_balancer_set_external_ids(sbrec_lb, &external_ids); - free(lb_id); - } else { - sbrec_lb = sb_lb->slb; - lb_dpg = sb_lb->dpg; - lb_lr_dpg = sb_lb->lr_dpg; - } - - /* Find or create datapath group for this load balancer. */ - if (!lb_dpg && lb_dps->n_nb_ls) { - struct sbrec_logical_dp_group *ls_datapath_group - = chassis_features->ls_dpg_column - ? sbrec_lb->ls_datapath_group - : sbrec_lb->datapath_group; /* deprecated */ - lb_dpg = ovn_dp_group_get_or_create( - ovnsb_txn, &ls_dp_groups, - ls_datapath_group, - lb_dps->n_nb_ls, lb_dps->nb_ls_map, - ods_size(ls_datapaths), true, - ls_datapaths, NULL); - } - if (!lb_lr_dpg && lb_dps->n_nb_lr) { - lb_lr_dpg = ovn_dp_group_get_or_create( - ovnsb_txn, &lr_dp_groups, - sbrec_lb->lr_datapath_group, - lb_dps->n_nb_lr, lb_dps->nb_lr_map, - ods_size(lr_datapaths), false, - NULL, lr_datapaths); - } - - /* Update columns. */ - sbrec_load_balancer_set_name(sbrec_lb, lb_dps->lb->nlb->name); - sbrec_load_balancer_set_vips(sbrec_lb, - ovn_northd_lb_get_vips(lb_dps->lb)); - sbrec_load_balancer_set_protocol(sbrec_lb, lb_dps->lb->nlb->protocol); - - if (chassis_features->ls_dpg_column) { - sbrec_load_balancer_set_ls_datapath_group( - sbrec_lb, lb_dpg ? lb_dpg->dp_group : NULL - ); - sbrec_load_balancer_set_datapath_group(sbrec_lb, NULL); - } else { - /* datapath_group column is deprecated. */ - sbrec_load_balancer_set_ls_datapath_group(sbrec_lb, NULL); - sbrec_load_balancer_set_datapath_group( - sbrec_lb, lb_dpg ? lb_dpg->dp_group : NULL - ); - } - - sbrec_load_balancer_set_lr_datapath_group( - sbrec_lb, lb_lr_dpg ? lb_lr_dpg->dp_group : NULL - ); - sbrec_load_balancer_set_options(sbrec_lb, &options); - /* Clearing 'datapaths' column, since 'dp_group' is in use. */ - sbrec_load_balancer_set_datapaths(sbrec_lb, NULL, 0); - smap_destroy(&options); - } - - struct ovn_dp_group *dpg; - HMAP_FOR_EACH_POP (dpg, node, &ls_dp_groups) { - bitmap_free(dpg->bitmap); - free(dpg); - } - hmap_destroy(&ls_dp_groups); - - HMAP_FOR_EACH_POP (dpg, node, &lr_dp_groups) { - bitmap_free(dpg->bitmap); - free(dpg); - } - hmap_destroy(&lr_dp_groups); - - struct sb_lb *sb_lb; - HMAP_FOR_EACH_POP (sb_lb, hmap_node, &sb_lbs) { - free(sb_lb); - } - hmap_destroy(&sb_lbs); - - /* Datapath_Binding.load_balancers is not used anymore, it's still in the - * schema for compatibility reasons. Reset it to empty, just in case. - */ - struct ovn_datapath *od; - HMAP_FOR_EACH (od, key_node, &ls_datapaths->datapaths) { - ovs_assert(od->nbs); - - if (od->sb->n_load_balancers) { - sbrec_datapath_binding_set_load_balancers(od->sb, NULL, 0); - } - } - HMAP_FOR_EACH (od, key_node, &lr_datapaths->datapaths) { - ovs_assert(od->nbr); - - if (od->sb->n_load_balancers) { - sbrec_datapath_binding_set_load_balancers(od->sb, NULL, 0); - } - } -} - -bool -check_sb_lb_duplicates(const struct sbrec_load_balancer_table *table) -{ - struct sset existing_nb_lb_uuids = - SSET_INITIALIZER(&existing_nb_lb_uuids); - const struct sbrec_load_balancer *sbrec_lb; - bool duplicates = false; - - SBREC_LOAD_BALANCER_TABLE_FOR_EACH (sbrec_lb, table) { - const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); - if (nb_lb_uuid && !sset_add(&existing_nb_lb_uuids, nb_lb_uuid)) { - duplicates = true; - break; - } - } - - sset_destroy(&existing_nb_lb_uuids); - return duplicates; -} - /* Syncs the SB port binding for the ovn_port 'op' of a logical switch port. * Caller should make sure that the OVN SB IDL txn is not NULL. Presently it * only syncs the nat column of port binding corresponding to the 'op->nbsp' */ diff --git a/northd/northd.h b/northd/northd.h index 297b1a65b9..579edb8bdf 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -715,12 +715,6 @@ 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 *, - struct ovn_datapaths *ls_datapaths, - struct ovn_datapaths *lr_datapaths, - struct hmap *lbs, - struct chassis_features *chassis_features); -bool check_sb_lb_duplicates(const struct sbrec_load_balancer_table *); struct lr_stateful_table; void sync_pbs(struct ovsdb_idl_txn *, struct hmap *ls_ports, diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 263eb343eb..5c33a8a6c2 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -2938,6 +2938,8 @@ sw1_sb_uuid=$(fetch_column datapath_binding _uuid external_ids:name=sw1) echo "$sw0_sb_uuid" > sw_sb_uuids echo "$sw1_sb_uuid" >> sw_sb_uuids +lb0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lb0) + echo echo "__file__:__line__: Check that SB lb0 has sw0 and sw1 in datapaths column." AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl @@ -2945,6 +2947,8 @@ AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Gr $(cat sw_sb_uuids | sort) ]) +lbg0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg0) + echo echo "__file__:__line__: Check that SB lbg0 has sw0 and sw1 in datapaths column." AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl @@ -3014,6 +3018,64 @@ echo "__file__:__line__: Set hairpin_snat_ip on lb1 and check that SB DB is upda check ovn-nbctl --wait=sb set Load_Balancer lb1 options:hairpin_snat_ip="42.42.42.42 4242::4242" check_column "$lb1_uuid" sb:load_balancer _uuid name=lb1 options='{hairpin_orig_tuple="true", hairpin_snat_ip="42.42.42.42 4242::4242"}' +echo +echo "__file__:__line__: Set option:bar=foo on lbg1 and check that sync_to_sb_lb engine node didn't recompute." + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb set load_balancer lbg1 options:bar=foo +check_engine_stats sync_to_sb_lb norecompute compute + +# Manually clear the sb:load_balancer.ls_datapath_group column for +# all load balancers and check that it is resynced back when the +# NB lbg1 is modified. + +echo +echo "__file__:__line__: Clear the ls_datapath_group column of all the SB load balancers." + +for l in $(ovn-sbctl --bare --columns _uuid list load_balancer) +do + check ovn-sbctl clear load_balancer $l ls_datapath_group +done + +lbg1_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg1) +AT_CHECK([test "$lbg1_dp_group" = ""]) + +echo +echo "__file__:__line__: Set option:foo=bar on lbg1 and check that sync_to_sb_lb engine node recomputed." + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb set load_balancer lbg1 options:foo=bar +check_engine_stats sync_to_sb_lb recompute compute + +# Manually clear the sb:load_balancer.lr_datapath_group column for +# all load balancers and check that it is resynced back when the +# NB lbg1 is modified. + +echo +echo "__file__:__line__: Clear the lr_datapath_group column of all the SB load balancers." + +for l in $(ovn-sbctl --bare --columns _uuid list load_balancer) +do + check ovn-sbctl clear load_balancer $l lr_datapath_group +done + +echo +echo "__file__:__line__: Set option:foo=foo on lbg1 and check that sync_to_sb_lb engine node recomputed." + +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats +check ovn-nbctl --wait=sb set load_balancer lbg1 options:foo=foo +check_engine_stats sync_to_sb_lb recompute compute + +lbg1_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg1) + +echo +echo "__file__:__line__: Check that SB lbg1 has sw0 and sw1 in datapaths column." + +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl + | grep -A1 $lbg1_dp_group | tail -1 | tr ' ' '\n' | sort], [0], [dnl +$(cat sw_sb_uuids | sort) +]) + echo echo "__file__:__line__: Delete load balancers lb1 and lbg1 and check that datapath sw1's load_balancers is still empty." @@ -3024,6 +3086,8 @@ echo echo "__file__:__line__: Delete switch sw0." check ovn-nbctl --wait=sb ls-del sw0 +lb0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lb0) + echo echo "__file__:__line__: Check that SB lb0 has only sw1 in datapaths column." AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl @@ -3031,6 +3095,8 @@ AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Gr $sw1_sb_uuid ]) +lbg0_dp_group=$(fetch_column sb:load_balancer ls_datapath_group name=lbg0) + echo echo "__file__:__line__: Check that SB lbg0 has only sw1 in datapaths column." AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl @@ -10521,8 +10587,7 @@ check ovn-nbctl --wait=sb lb-add lb1 10.0.0.10:80 10.0.0.3:80 check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute - +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10531,7 +10596,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10541,7 +10606,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10550,7 +10615,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10560,7 +10625,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10618,7 +10683,7 @@ check_engine_stats lr_stateful norecompute compute # A LB applied to a switch/router triggers: # - a recompute in the first iteration (handling northd change) # - a compute in the second iteration (handling SB update) -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE((1)) @@ -10631,7 +10696,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) # Cleanup the vip of lb1. @@ -10642,7 +10707,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) # Set the vips of lb1 back @@ -10653,7 +10718,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) # Add another vip to lb1 @@ -10664,7 +10729,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE(1) # Disassociate lb1 from sw0. There should be a full recompute of northd engine node. @@ -10687,7 +10752,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10708,7 +10773,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Modify the backend of the lb1 vip @@ -10718,7 +10783,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Cleanup the vip of lb1. @@ -10728,7 +10793,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Set the vips of lb1 back @@ -10738,7 +10803,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Add another vip to lb1 @@ -10748,7 +10813,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10779,7 +10844,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10796,7 +10861,7 @@ check ovn-nbctl --wait=sb add load_balancer_group . load_Balancer $lb1_uuid check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10806,7 +10871,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute # Update lb and this should not result in northd recompute check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10816,7 +10881,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute # Modify the backend of the lb1 vip check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10826,7 +10891,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Cleanup the vip of lb1. @@ -10837,7 +10902,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Set the vips of lb1 back @@ -10848,7 +10913,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Add another vip to lb1 @@ -10859,7 +10924,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10875,7 +10940,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Modify the backend of the lb1 vip @@ -10885,7 +10950,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Cleanup the vip of lb1. @@ -10895,7 +10960,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Set the vips of lb1 back @@ -10905,7 +10970,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Add another vip to lb1 @@ -10915,7 +10980,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10935,7 +11000,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10979,7 +11044,7 @@ check_engine_stats northd norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10989,7 +11054,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -10998,7 +11063,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -11008,7 +11073,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -11018,7 +11083,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -11028,7 +11093,7 @@ check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -11059,7 +11124,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Deleting lb2 should result in lflow recompute as it is @@ -11071,7 +11136,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats ls_stateful norecompute compute check_engine_stats lflow norecompute compute -check_engine_stats sync_to_sb_lb recompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -11281,6 +11346,7 @@ check ovn-nbctl --wait=sb ls-lb-add sw0 lb1 check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lflow norecompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Clear the VIPs of lb1 @@ -11289,6 +11355,7 @@ check ovn-nbctl --wait=sb clear load_balancer . vips check_engine_stats lb_data norecompute compute check_engine_stats northd norecompute compute check_engine_stats lflow norecompute compute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats @@ -11296,6 +11363,7 @@ check ovn-nbctl --wait=sb lb-del lb1 check_engine_stats lb_data norecompute compute check_engine_stats northd recompute nocompute check_engine_stats lflow recompute nocompute +check_engine_stats sync_to_sb_lb recompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE AT_CLEANUP @@ -11544,6 +11612,7 @@ check_engine_stats northd recompute nocompute check_engine_stats lr_nat recompute nocompute check_engine_stats lr_stateful recompute nocompute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb recompute nocompute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11557,6 +11626,7 @@ check_engine_stats northd recompute compute check_engine_stats lr_nat recompute nocompute check_engine_stats lr_stateful recompute nocompute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb recompute nocompute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11569,6 +11639,7 @@ check_engine_stats northd recompute compute check_engine_stats lr_nat recompute nocompute check_engine_stats lr_stateful recompute nocompute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb recompute nocompute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11595,6 +11666,7 @@ check_engine_stats northd recompute nocompute check_engine_stats lr_nat recompute nocompute check_engine_stats lr_stateful recompute nocompute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb recompute nocompute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11607,6 +11679,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_nat norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Update the NAT options column @@ -11616,6 +11689,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_nat norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Update the NAT external_ip column @@ -11626,6 +11700,7 @@ check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Update the NAT logical_ip column @@ -11636,6 +11711,7 @@ check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Update the NAT type @@ -11646,6 +11722,7 @@ check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Create a dnat_and_snat NAT with external_mac and logical_port @@ -11656,6 +11733,7 @@ check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE nat2_uuid=$(ovn-nbctl --bare --columns _uuid find nat logical_ip=10.0.0.4) @@ -11667,6 +11745,7 @@ check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Create a load balancer and add the lb vip as NAT @@ -11683,6 +11762,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11694,6 +11774,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11705,6 +11786,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11716,6 +11798,7 @@ check_engine_stats northd norecompute compute check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11727,6 +11810,7 @@ check_engine_stats lr_nat norecompute compute check_engine_stats lr_stateful norecompute compute check_engine_stats lflow norecompute compute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb norecompute compute CHECK_NO_CHANGE_AFTER_RECOMPUTE # Create router Policy @@ -11736,6 +11820,7 @@ check_engine_stats northd recompute nocompute check_engine_stats lr_nat recompute nocompute check_engine_stats lr_stateful recompute nocompute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb recompute nocompute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE @@ -11745,6 +11830,7 @@ check_engine_stats northd recompute nocompute check_engine_stats lr_nat recompute nocompute check_engine_stats lr_stateful recompute nocompute check_engine_stats sync_to_sb_pb recompute nocompute +check_engine_stats sync_to_sb_lb recompute nocompute check_engine_stats lflow recompute nocompute CHECK_NO_CHANGE_AFTER_RECOMPUTE