On Wed, Aug 3, 2022 at 4:44 PM Ilya Maximets <i.maxim...@ovn.org> wrote:
> Some CMSes, like ovn-kubernetes, tend to create load balancers attached > to a big number of logical switches or routers. For each of these > load balancers northd creates a record in Load_Balancer table of the > Southbound database with all the logical datapaths (switches, routers) > listed in the 'datapaths' column. All these logical datapaths are > references to datapath bindings. With large number of load balancers > like these applied to the same set of load balancers, the size of > the Southbound database can grow significantly and these references > can take up to 90% of all the traffic between Sb DB and ovn-controllers. > > For example, while creating 3 load balancers (1 for tcp, udp and sctp) > in a 250-node cluster in ovn-heater cluster-density test, the database > update sent to every ovn-controller is about 40 KB in size, out of > which 36 KB are just UUIDs of 250 logical datapaths repeated 3 times. > > Introducing a new column 'datapath_group' in a Load_Balancer table, > so we can create a group once and just refer to it from each load > balancer. This saves a lot of CPU time, memory and network bandwidth. > Re-using already existing Logical_DP_Group table to store these groups. > > In 250 node cluster-density test with ovn-heater that creates 30K load > balancers applied to all 250 logical switches the following improvement > was observed: > > - Southbound database size decreased from 310 MB to 118 MB. > - CPU time on Southbound ovsdb-server process decreased by a > factor of 7, from ~35 minutes per server to ~5. > - Memory consumption on Southbound ovsdb-server process decreased > from 12 GB (peaked at ~14) RSS down to ~1 GB (peaked at ~2). > - Memory consumption on ovn-controller processes decreased > by 400 MB on each node, from 1300 MB to 900 MB. Similar decrease > observed for ovn-northd as well. > > We're adding some extra work to ovn-northd process with this change > to find/create datapath groups. CPU time in the test above increased > by ~10%, but overall round trip time for changes in OVN to be > propagated to OVN controllers is still noticeably lower due to > improvements in other components like Sb DB. > > Implementation details: > - Groups are not shared between logical flows and load balancers, > so there could be duplicated groups this way, but that should > not be a big problem. Sharing groups will require some code > re-structuring with unclear benefits. > - ovn-controller and ovn-sbctl are parsing both the 'datapaths' column > and the 'datapath_group' to keep them backward compatible. > - Load_Balancer table is not conditionally monitored by ovn-controller > right now, so not changing that behavior. If conditional monitoring > will be introduced later, same considerations as for logical flows > should be applied. > > Signed-off-by: Ilya Maximets <i.maxim...@ovn.org> > --- > controller/lflow.c | 44 ++++++++-- > controller/ovn-controller.c | 54 ++++++++---- > northd/northd.c | 168 ++++++++++++++++++++++++------------ > ovn-sb.ovsschema | 8 +- > ovn-sb.xml | 5 ++ > tests/ovn-northd.at | 68 ++++++++++++--- > utilities/ovn-sbctl.c | 40 +++++---- > 7 files changed, 278 insertions(+), 109 deletions(-) > > diff --git a/controller/lflow.c b/controller/lflow.c > index 6055097b5..eef44389f 100644 > --- a/controller/lflow.c > +++ b/controller/lflow.c > @@ -2063,6 +2063,20 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb > *lb, > ofpbuf_uninit(&ofpacts); > } > > +static void > +add_lb_ct_snat_hairpin_for_dp(const struct ovn_controller_lb *lb, > + const struct sbrec_datapath_binding > *datapath, > + struct match *dp_match, > + struct ofpbuf *dp_acts, > + struct ovn_desired_flow_table *flow_table) > +{ > + match_set_metadata(dp_match, htonll(datapath->tunnel_key)); > + ofctrl_add_or_append_flow(flow_table, OFTABLE_CT_SNAT_HAIRPIN, 200, > + lb->slb->header_.uuid.parts[0], > + dp_match, dp_acts, &lb->slb->header_.uuid, > + NX_CTLR_NO_METER, NULL); > +} > + > static void > add_lb_ct_snat_hairpin_dp_flows(struct ovn_controller_lb *lb, > uint32_t id, > @@ -2088,12 +2102,15 @@ add_lb_ct_snat_hairpin_dp_flows(struct > ovn_controller_lb *lb, > struct match dp_match = MATCH_CATCHALL_INITIALIZER; > > for (size_t i = 0; i < lb->slb->n_datapaths; i++) { > - match_set_metadata(&dp_match, > - htonll(lb->slb->datapaths[i]->tunnel_key)); > - ofctrl_add_or_append_flow(flow_table, OFTABLE_CT_SNAT_HAIRPIN, > 200, > - lb->slb->header_.uuid.parts[0], > - &dp_match, &dp_acts, > &lb->slb->header_.uuid, > - NX_CTLR_NO_METER, NULL); > + add_lb_ct_snat_hairpin_for_dp(lb, lb->slb->datapaths[i], > + &dp_match, &dp_acts, flow_table); > + } > + if (lb->slb->datapath_group) { > + for (size_t i = 0; i < lb->slb->datapath_group->n_datapaths; i++) > { > + add_lb_ct_snat_hairpin_for_dp( > + lb, lb->slb->datapath_group->datapaths[i], > + &dp_match, &dp_acts, flow_table); > + } > } > > ofpbuf_uninit(&dp_acts); > @@ -2351,7 +2368,20 @@ consider_lb_hairpin_flows(const struct > sbrec_load_balancer *sbrec_lb, > } > } > > - if (i == sbrec_lb->n_datapaths) { > + if (sbrec_lb->n_datapaths && i == sbrec_lb->n_datapaths) { > + return; > + } > + > + struct sbrec_logical_dp_group *dp_group = sbrec_lb->datapath_group; > + > + for (i = 0; dp_group && i < dp_group->n_datapaths; i++) { > + if (get_local_datapath(local_datapaths, > + dp_group->datapaths[i]->tunnel_key)) { > + break; > + } > + } > + > + if (dp_group && i == dp_group->n_datapaths) { > return; > } > > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c > index 5449743e8..46de9e710 100644 > --- a/controller/ovn-controller.c > +++ b/controller/ovn-controller.c > @@ -2210,6 +2210,33 @@ load_balancers_by_dp_find(struct hmap *lbs, > return NULL; > } > > +static void > +load_balancers_by_dp_add_one(const struct hmap *local_datapaths, > + const struct sbrec_datapath_binding > *datapath, > + const struct sbrec_load_balancer *lb, > + struct hmap *lbs) > +{ > + struct local_datapath *ldp = > + get_local_datapath(local_datapaths, datapath->tunnel_key); > + > + if (!ldp) { > + return; > + } > + > + struct load_balancers_by_dp *lbs_by_dp = > + load_balancers_by_dp_find(lbs, ldp->datapath); > + if (!lbs_by_dp) { > + lbs_by_dp = load_balancers_by_dp_create(lbs, ldp->datapath); > + } > + > + if (lbs_by_dp->n_dp_lbs == lbs_by_dp->n_allocated_dp_lbs) { > + lbs_by_dp->dp_lbs = x2nrealloc(lbs_by_dp->dp_lbs, > + &lbs_by_dp->n_allocated_dp_lbs, > + sizeof *lbs_by_dp->dp_lbs); > + } > + lbs_by_dp->dp_lbs[lbs_by_dp->n_dp_lbs++] = lb; > +} > + > /* Builds and returns a hmap of 'load_balancers_by_dp', one record for > each > * local datapath. > */ > @@ -2223,25 +2250,14 @@ load_balancers_by_dp_init(const struct hmap > *local_datapaths, > const struct sbrec_load_balancer *lb; > SBREC_LOAD_BALANCER_TABLE_FOR_EACH (lb, lb_table) { > for (size_t i = 0; i < lb->n_datapaths; i++) { > - struct local_datapath *ldp = > - get_local_datapath(local_datapaths, > - lb->datapaths[i]->tunnel_key); > - if (!ldp) { > - continue; > - } > - > - struct load_balancers_by_dp *lbs_by_dp = > - load_balancers_by_dp_find(lbs, ldp->datapath); > - if (!lbs_by_dp) { > - lbs_by_dp = load_balancers_by_dp_create(lbs, > ldp->datapath); > - } > - > - if (lbs_by_dp->n_dp_lbs == lbs_by_dp->n_allocated_dp_lbs) { > - lbs_by_dp->dp_lbs = x2nrealloc(lbs_by_dp->dp_lbs, > - > &lbs_by_dp->n_allocated_dp_lbs, > - sizeof *lbs_by_dp->dp_lbs); > - } > - lbs_by_dp->dp_lbs[lbs_by_dp->n_dp_lbs++] = lb; > + load_balancers_by_dp_add_one(local_datapaths, > + lb->datapaths[i], lb, lbs); > + } > + for (size_t i = 0; lb->datapath_group > + && i < lb->datapath_group->n_datapaths; i++) { > + load_balancers_by_dp_add_one(local_datapaths, > + lb->datapath_group->datapaths[i], > + lb, lbs); > } > } > return lbs; > diff --git a/northd/northd.c b/northd/northd.c > index 0fcd3a642..c404dbdec 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -4249,6 +4249,48 @@ build_lb_port_related_data(struct hmap *datapaths, > struct hmap *ports, > build_lswitch_lbs_from_lrouter(datapaths, lbs); > } > > + > +struct ovn_dp_group { > + struct hmapx map; > + struct sbrec_logical_dp_group *dp_group; > + struct hmap_node node; > +}; > + > +static struct ovn_dp_group * > +ovn_dp_group_find(const struct hmap *dp_groups, > + const struct hmapx *od, uint32_t hash) > +{ > + struct ovn_dp_group *dpg; > + > + HMAP_FOR_EACH_WITH_HASH (dpg, node, hash, dp_groups) { > + if (hmapx_equals(&dpg->map, od)) { > + return dpg; > + } > + } > + return NULL; > +} > + > +static struct sbrec_logical_dp_group * > +ovn_sb_insert_logical_dp_group(struct ovsdb_idl_txn *ovnsb_txn, > + const struct hmapx *od) > +{ > + struct sbrec_logical_dp_group *dp_group; > + const struct sbrec_datapath_binding **sb; > + const struct hmapx_node *node; > + int n = 0; > + > + sb = xmalloc(hmapx_count(od) * sizeof *sb); > + HMAPX_FOR_EACH (node, od) { > + sb[n++] = ((struct ovn_datapath *) node->data)->sb; > + } > + dp_group = sbrec_logical_dp_group_insert(ovnsb_txn); > + sbrec_logical_dp_group_set_datapaths( > + dp_group, (struct sbrec_datapath_binding **) sb, n); > + free(sb); > + > + return dp_group; > +} > + > /* Syncs relevant load balancers (applied to logical switches) to the > * Southbound database. > */ > @@ -4256,9 +4298,13 @@ static void > sync_lbs(struct northd_input *input_data, struct ovsdb_idl_txn *ovnsb_txn, > struct hmap *datapaths, struct hmap *lbs) > { > + struct hmap dp_groups = HMAP_INITIALIZER(&dp_groups); > struct ovn_northd_lb *lb; > > - /* Delete any stale SB load balancer rows. */ > + /* Delete any stale SB load balancer rows and collect existing valid > + * datapath groups. */ > + struct hmapx existing_sb_dp_groups = > + HMAPX_INITIALIZER(&existing_sb_dp_groups); > struct hmapx existing_lbs = HMAPX_INITIALIZER(&existing_lbs); > const struct sbrec_load_balancer *sbrec_lb; > SBREC_LOAD_BALANCER_TABLE_FOR_EACH_SAFE (sbrec_lb, > @@ -4281,11 +4327,46 @@ sync_lbs(struct northd_input *input_data, struct > ovsdb_idl_txn *ovnsb_txn, > lb = ovn_northd_lb_find(lbs, &lb_uuid); > if (!lb || !lb->n_nb_ls || !hmapx_add(&existing_lbs, lb)) { > sbrec_load_balancer_delete(sbrec_lb); > - } else { > - lb->slb = sbrec_lb; > + continue; > + } > + > + lb->slb = sbrec_lb; > + > + /* Collect the datapath group. */ > + struct sbrec_logical_dp_group *dp_group = > sbrec_lb->datapath_group; > + > + if (!dp_group || !hmapx_add(&existing_sb_dp_groups, dp_group)) { > + continue; > + } > + > + struct ovn_dp_group *dpg = xzalloc(sizeof *dpg); > + size_t i; > + > + hmapx_init(&dpg->map); > + for (i = 0; i < dp_group->n_datapaths; i++) { > + struct ovn_datapath *datapath_od; > + > + datapath_od = ovn_datapath_from_sbrec(datapaths, > + dp_group->datapaths[i]); > + if (!datapath_od || ovn_datapath_is_stale(datapath_od)) { > + break; > + } > + hmapx_add(&dpg->map, datapath_od); > + } > + if (i == dp_group->n_datapaths) { > + uint32_t hash = hash_int(hmapx_count(&dpg->map), 0); > + > + if (!ovn_dp_group_find(&dp_groups, &dpg->map, hash)) { > + dpg->dp_group = dp_group; > + hmap_insert(&dp_groups, &dpg->node, hash); > + continue; > + } > } > + hmapx_destroy(&dpg->map); > + free(dpg); > } > hmapx_destroy(&existing_lbs); > + hmapx_destroy(&existing_sb_dp_groups); > > /* Create SB Load balancer records if not present and sync > * the SB load balancer columns. */ > @@ -4302,13 +4383,6 @@ sync_lbs(struct northd_input *input_data, struct > ovsdb_idl_txn *ovnsb_txn, > smap_clone(&options, &lb->nlb->options); > smap_replace(&options, "hairpin_orig_tuple", "true"); > > - struct sbrec_datapath_binding **lb_dps = > - xmalloc(lb->n_nb_ls * sizeof *lb_dps); > - for (size_t i = 0; i < lb->n_nb_ls; i++) { > - lb_dps[i] = CONST_CAST(struct sbrec_datapath_binding *, > - lb->nb_ls[i]->sb); > - } > - > if (!lb->slb) { > sbrec_lb = sbrec_load_balancer_insert(ovnsb_txn); > lb->slb = sbrec_lb; > @@ -4319,15 +4393,44 @@ sync_lbs(struct northd_input *input_data, struct > ovsdb_idl_txn *ovnsb_txn, > sbrec_load_balancer_set_external_ids(sbrec_lb, &external_ids); > free(lb_id); > } > + > + /* Find datapath group for this load balancer. */ > + struct hmapx lb_dps = HMAPX_INITIALIZER(&lb_dps); > + struct ovn_dp_group *dpg; > + uint32_t hash; > + > + for (size_t i = 0; i < lb->n_nb_ls; i++) { > + hmapx_add(&lb_dps, lb->nb_ls[i]); > + } > + > + hash = hash_int(hmapx_count(&lb_dps), 0); > + dpg = ovn_dp_group_find(&dp_groups, &lb_dps, hash); > + if (!dpg) { > + dpg = xzalloc(sizeof *dpg); > + dpg->dp_group = ovn_sb_insert_logical_dp_group(ovnsb_txn, > &lb_dps); > + hmapx_clone(&dpg->map, &lb_dps); > + hmap_insert(&dp_groups, &dpg->node, hash); > + } > + hmapx_destroy(&lb_dps); > + > + /* Update columns. */ > sbrec_load_balancer_set_name(lb->slb, lb->nlb->name); > sbrec_load_balancer_set_vips(lb->slb, &lb->nlb->vips); > sbrec_load_balancer_set_protocol(lb->slb, lb->nlb->protocol); > - sbrec_load_balancer_set_datapaths(lb->slb, lb_dps, lb->n_nb_ls); > + sbrec_load_balancer_set_datapath_group(lb->slb, dpg->dp_group); > sbrec_load_balancer_set_options(lb->slb, &options); > + /* Clearing 'datapaths' column, since 'dp_group' is in use. */ > + sbrec_load_balancer_set_datapaths(lb->slb, NULL, 0); > smap_destroy(&options); > - free(lb_dps); > } > > + struct ovn_dp_group *dpg; > + HMAP_FOR_EACH_POP (dpg, node, &dp_groups) { > + hmapx_destroy(&dpg->map); > + free(dpg); > + } > + hmap_destroy(&dp_groups); > + > /* Datapath_Binding.load_balancers is not used anymore, it's still in > the > * schema for compatibility reasons. Reset it to empty, just in case. > */ > @@ -14058,47 +14161,6 @@ build_lswitch_and_lrouter_flows(const struct hmap > *datapaths, > build_lswitch_flows(datapaths, lflows); > } > > -struct ovn_dp_group { > - struct hmapx map; > - struct sbrec_logical_dp_group *dp_group; > - struct hmap_node node; > -}; > - > -static struct ovn_dp_group * > -ovn_dp_group_find(const struct hmap *dp_groups, > - const struct hmapx *od, uint32_t hash) > -{ > - struct ovn_dp_group *dpg; > - > - HMAP_FOR_EACH_WITH_HASH (dpg, node, hash, dp_groups) { > - if (hmapx_equals(&dpg->map, od)) { > - return dpg; > - } > - } > - return NULL; > -} > - > -static struct sbrec_logical_dp_group * > -ovn_sb_insert_logical_dp_group(struct ovsdb_idl_txn *ovnsb_txn, > - const struct hmapx *od) > -{ > - struct sbrec_logical_dp_group *dp_group; > - const struct sbrec_datapath_binding **sb; > - const struct hmapx_node *node; > - int n = 0; > - > - sb = xmalloc(hmapx_count(od) * sizeof *sb); > - HMAPX_FOR_EACH (node, od) { > - sb[n++] = ((struct ovn_datapath *) node->data)->sb; > - } > - dp_group = sbrec_logical_dp_group_insert(ovnsb_txn); > - sbrec_logical_dp_group_set_datapaths( > - dp_group, (struct sbrec_datapath_binding **) sb, n); > - free(sb); > - > - return dp_group; > -} > - > static void > ovn_sb_set_lflow_logical_dp_group( > struct ovsdb_idl_txn *ovnsb_txn, > diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema > index 3b78ea6f6..8770fc01d 100644 > --- a/ovn-sb.ovsschema > +++ b/ovn-sb.ovsschema > @@ -1,7 +1,7 @@ > { > "name": "OVN_Southbound", > - "version": "20.23.0", > - "cksum": "4045988377 28575", > + "version": "20.24.0", > + "cksum": "3074645903 28786", > "tables": { > "SB_Global": { > "columns": { > @@ -505,6 +505,10 @@ > "type": {"key": {"type": "uuid", > "refTable": "Datapath_Binding"}, > "min": 0, "max": "unlimited"}}, > + "datapath_group": > + {"type": {"key": {"type": "uuid", > + "refTable": "Logical_DP_Group"}, > + "min": 0, "max": 1}}, > "options": { > "type": {"key": "string", > "value": "string", > diff --git a/ovn-sb.xml b/ovn-sb.xml > index 59ad3aa2d..74377a47d 100644 > --- a/ovn-sb.xml > +++ b/ovn-sb.xml > @@ -4589,6 +4589,11 @@ tcp.flags = RST; > Datapaths to which this load balancer applies to. > </column> > > + <column name="datapath_group"> > + The group of datapaths to which this load balancer applies to. This > + means that the same load balancer applies to all datapaths in a > group. > + </column> > + > <group title="Load_Balancer options"> > <column name="options" key="hairpin_snat_ip"> > IP to be used as source IP for packets that have been hair-pinned > after > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index ae0f66ad6..38d2baf07 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -2469,13 +2469,23 @@ lbg0_uuid=$(fetch_column sb:load_balancer _uuid > name=lbg0) > echo > echo "__file__:__line__: Check that SB lb0 has sw0 in datapaths column." > > -check_column "$sw0_sb_uuid" sb:load_balancer datapaths name=lb0 > +lb0_dp_group=$(fetch_column sb:load_balancer datapath_group name=lb0) > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lb0_dp_group | tail -1], [0], [dnl > +$sw0_sb_uuid > +]) > + > check_column "" sb:datapath_binding load_balancers external_ids:name=sw0 > > echo > echo "__file__:__line__: Check that SB lbg0 has sw0 in datapaths column." > > -check_column "$sw0_sb_uuid" sb:load_balancer datapaths name=lbg0 > +lbg0_dp_group=$(fetch_column sb:load_balancer datapath_group name=lbg0) > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lbg0_dp_group | tail -1], [0], [dnl > +$sw0_sb_uuid > +]) > + > check_column "" sb:datapath_binding load_balancers external_ids:name=sw0 > > check ovn-nbctl --wait=sb set load_balancer lb0 vips:"10.0.0.20\:90"=" > 20.0.0.4:8080,30.0.0.4:8080" > @@ -2499,23 +2509,43 @@ check ovn-nbctl --wait=sb lr-lb-add lr0 lb0 > > echo > echo "__file__:__line__: Check that SB lb0 has only sw0 in datapaths > column." > -check_column "$sw0_sb_uuid" sb:load_balancer datapaths name=lb0 > +lb0_dp_group=$(fetch_column sb:load_balancer datapath_group name=lb0) > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lb0_dp_group | tail -1], [0], [dnl > +$sw0_sb_uuid > +]) > > echo > echo "__file__:__line__: Check that SB lbg0 has only sw0 in datapaths > column." > -check_column "$sw0_sb_uuid" sb:load_balancer datapaths name=lbg0 > +lbg0_dp_group=$(fetch_column sb:load_balancer datapath_group name=lbg0) > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lbg0_dp_group | tail -1], [0], [dnl > +$sw0_sb_uuid > +]) > > check ovn-nbctl ls-add sw1 -- add logical_switch sw1 load_balancer_group > $lbg > check ovn-nbctl --wait=sb ls-lb-add sw1 lb0 > 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 > + > echo > echo "__file__:__line__: Check that SB lb0 has sw0 and sw1 in datapaths > column." > -check_column "$sw0_sb_uuid $sw1_sb_uuid" sb:load_balancer datapaths > name=lb0 > +lb0_dp_group=$(fetch_column sb:load_balancer datapath_group name=lb0) > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lb0_dp_group | tail -1 | tr ' ' '\n' | > sort], [0], [dnl > +$(cat sw_sb_uuids | sort) > +]) > > echo > echo "__file__:__line__: Check that SB lbg0 has sw0 and sw1 in datapaths > column." > -check_column "$sw0_sb_uuid $sw1_sb_uuid" sb:load_balancer datapaths > name=lbg0 > +lbg0_dp_group=$(fetch_column sb:load_balancer datapath_group name=lbg0) > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lbg0_dp_group | tail -1 | tr ' ' '\n' | > sort], [0], [dnl > +$(cat sw_sb_uuids | sort) > +]) > + > check_column "" sb:datapath_binding load_balancers external_ids:name=sw1 > > check ovn-nbctl --wait=sb lb-add lb1 10.0.0.30:80 20.0.0.50:8080 udp > @@ -2542,18 +2572,26 @@ echo "__file__:__line__: Check that SB lbg1 has > vips and protocol columns are se > check_column "20.0.0.30:80=20.0.0.50:8080 udp" sb:load_balancer > vips,protocol name=lbg1 > > lb1_uuid=$(fetch_column sb:load_balancer _uuid name=lb1) > +lb1_dp_group=$(fetch_column sb:load_balancer datapath_group name=lb1) > > echo > echo "__file__:__line__: Check that SB lb1 has sw1 in datapaths column." > > -check_column "$sw1_sb_uuid" sb:load_balancer datapaths name=lb1 > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lb1_dp_group | tail -1], [0], [dnl > +$sw1_sb_uuid > +]) > > lbg1_uuid=$(fetch_column sb:load_balancer _uuid name=lbg1) > +lbg1_dp_group=$(fetch_column sb:load_balancer datapath_group name=lbg1) > > echo > echo "__file__:__line__: Check that SB lbg1 has sw0 and sw1 in datapaths > column." > > -check_column "$sw0_sb_uuid $sw1_sb_uuid" sb:load_balancer datapaths > name=lbg1 > +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__: check that datapath sw1 has no entry in the > load_balancers column." > @@ -5335,9 +5373,9 @@ ovn_start > check ovn-nbctl ls-add ls -- lb-add lb1 10.0.0.1:80 10.0.0.2:80 -- > ls-lb-add ls lb1 > check ovn-nbctl --wait=sb sync > > -dps=$(fetch_column Load_Balancer datapaths) > +dps=$(fetch_column Load_Balancer datapath_group) > nlb=$(fetch_column nb:Load_Balancer _uuid) > -AT_CHECK([ovn-sbctl create Load_Balancer name=lb1 datapaths="$dps" > external_ids="lb_id=$nlb"], [0], [ignore]) > +AT_CHECK([ovn-sbctl create Load_Balancer name=lb1 datapath_group="$dps" > external_ids="lb_id=$nlb"], [0], [ignore]) > > check ovn-nbctl --wait=sb sync > check_row_count Load_Balancer 1 > @@ -7614,9 +7652,13 @@ AT_CHECK([grep "ls_in_lb" S1flows | sort], [0], [dnl > table=11(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst > == 172.16.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = > 172.16.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.2:80);) > ]) > > -s0_uuid=$(ovn-sbctl get datapath S0 _uuid) > -s1_uuid=$(ovn-sbctl get datapath S1 _uuid) > -check_column "$s0_uuid $s1_uuid" sb:load_balancer datapaths name=lb0 > +ovn-sbctl get datapath S0 _uuid > dp_uuids > +ovn-sbctl get datapath S1 _uuid >> dp_uuids > +lb_dp_group=$(ovn-sbctl --bare --columns datapath_group find > Load_Balancer name=lb0) > +AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find > Logical_DP_Group dnl > + | grep -A1 $lb_dp_group | tail -1 | tr ' ' '\n' | > sort], [0], [dnl > +$(cat dp_uuids | sort) > +]) > > ovn-nbctl --wait=sb set NB_Global . > options:install_ls_lb_from_router=false > > diff --git a/utilities/ovn-sbctl.c b/utilities/ovn-sbctl.c > index b008b5d0b..e35556d34 100644 > --- a/utilities/ovn-sbctl.c > +++ b/utilities/ovn-sbctl.c > @@ -335,6 +335,7 @@ pre_get_info(struct ctl_context *ctx) > ovsdb_idl_add_column(ctx->idl, &sbrec_mac_binding_col_mac); > > ovsdb_idl_add_column(ctx->idl, &sbrec_load_balancer_col_datapaths); > + ovsdb_idl_add_column(ctx->idl, > &sbrec_load_balancer_col_datapath_group); > ovsdb_idl_add_column(ctx->idl, &sbrec_load_balancer_col_vips); > ovsdb_idl_add_column(ctx->idl, &sbrec_load_balancer_col_name); > ovsdb_idl_add_column(ctx->idl, &sbrec_load_balancer_col_protocol); > @@ -826,6 +827,21 @@ cmd_lflow_list_chassis(struct ctl_context *ctx, > struct vconn *vconn, > } > } > > +static bool > +datapath_group_contains_datapath(const struct sbrec_logical_dp_group *g, > + const struct sbrec_datapath_binding *dp) > +{ > + if (!g || !dp) { > + return false; > + } > + for (size_t i = 0; i < g->n_datapaths; i++) { > + if (g->datapaths[i] == dp) { > + return true; > + } > + } > + return false; > +} > + > static void > cmd_lflow_list_load_balancers(struct ctl_context *ctx, struct vconn > *vconn, > const struct sbrec_datapath_binding > *datapath, > @@ -843,6 +859,10 @@ cmd_lflow_list_load_balancers(struct ctl_context > *ctx, struct vconn *vconn, > break; > } > } > + if (lb->datapath_group && !dp_found) { > + dp_found = > datapath_group_contains_datapath(lb->datapath_group, > + datapath); > + } > if (!dp_found) { > continue; > } > @@ -861,6 +881,11 @@ cmd_lflow_list_load_balancers(struct ctl_context > *ctx, struct vconn *vconn, > print_vflow_datapath_name(lb->datapaths[i], true, > &ctx->output); > } > + for (size_t i = 0; lb->datapath_group > + && i < lb->datapath_group->n_datapaths; > i++) { > + > print_vflow_datapath_name(lb->datapath_group->datapaths[i], > + true, &ctx->output); > + } > } > > ds_put_cstr(&ctx->output, "\n vips:\n"); > @@ -879,21 +904,6 @@ cmd_lflow_list_load_balancers(struct ctl_context > *ctx, struct vconn *vconn, > } > } > > -static bool > -datapath_group_contains_datapath(const struct sbrec_logical_dp_group *g, > - const struct sbrec_datapath_binding *dp) > -{ > - if (!g || !dp) { > - return false; > - } > - for (size_t i = 0; i < g->n_datapaths; i++) { > - if (g->datapaths[i] == dp) { > - return true; > - } > - } > - return false; > -} > - > static void > sbctl_lflow_add(struct sbctl_lflow **lflows, > size_t *n_flows, size_t *n_capacity, > -- > 2.34.3 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > Hi Ilya, looks good to me. Acked-by: Ales Musil <amu...@redhat.com> Regards, Ales -- Ales Musil Senior Software Engineer - OVN Core Red Hat EMEA <https://www.redhat.com> amu...@redhat.com IM: amusil <https://red.ht/sig> _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev