On 10/20/22 10:27, Lorenzo Bianconi wrote:
> Similar to single load balancers, add the capability to automatically
> deploy a load-balancer group on each logical-switch connected to a
> logical router where the load-balancer group has been installed by the
> CMS.
>
> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2125310
> Signed-off-by: Lorenzo Bianconi <[email protected]>
> ---
> Changes since v1:
> - loop over logical router instead of logical switches
> - introduce ovn_datapath_add_ls_peer to create ls peers of a given logical
> router
> - modify ovn_lb_group_add_ls to accept an array of logical switches
> ---
> lib/lb.h | 6 +++--
> northd/northd.c | 66 ++++++++++++++++++++++++---------------------
> northd/northd.h | 5 ++++
> tests/ovn-northd.at | 8 ++++++
> 4 files changed, 52 insertions(+), 33 deletions(-)
>
> diff --git a/lib/lb.h b/lib/lb.h
> index 80ac03399..c1aadd6dd 100644
> --- a/lib/lb.h
> +++ b/lib/lb.h
> @@ -144,9 +144,11 @@ struct ovn_lb_group *ovn_lb_group_find(const struct hmap
> *lb_groups,
> const struct uuid *);
>
> static inline void
> -ovn_lb_group_add_ls(struct ovn_lb_group *lb_group, struct ovn_datapath *ls)
> +ovn_lb_group_add_ls(struct ovn_lb_group *lb_group, size_t n,
> + struct ovn_datapath **ods)
> {
> - lb_group->ls[lb_group->n_ls++] = ls;
> + memcpy(&lb_group->ls[lb_group->n_ls], ods, n * sizeof *ods);
> + lb_group->n_ls += n;
> }
>
> static inline void
> diff --git a/northd/northd.c b/northd/northd.c
> index 6771ccce5..3ccdfc647 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -883,6 +883,7 @@ ovn_datapath_destroy(struct hmap *datapaths, struct
> ovn_datapath *od)
> ovn_destroy_tnlids(&od->port_tnlids);
> destroy_ipam_info(&od->ipam_info);
> free(od->router_ports);
> + free(od->ls_peers);
> destroy_nat_entries(od);
> destroy_router_external_ips(od);
> destroy_lb_for_datapath(od);
> @@ -966,6 +967,16 @@ ovn_datapath_add_router_port(struct ovn_datapath *od,
> struct ovn_port *op)
> od->router_ports[od->n_router_ports++] = op;
> }
>
> +static void
> +ovn_datapath_add_ls_peer(struct ovn_datapath *od, struct ovn_datapath *peer)
> +{
> + if (od->n_ls_peers == od->n_allocated_ls_peers) {
> + od->ls_peers = x2nrealloc(od->ls_peers, &od->n_allocated_ls_peers,
> + sizeof *od->ls_peers);
> + }
> + od->ls_peers[od->n_ls_peers++] = peer;
> +}
> +
> static bool
> lrouter_is_enabled(const struct nbrec_logical_router *lrouter)
> {
> @@ -2690,6 +2701,7 @@ join_logical_ports(struct northd_input *input_data,
> }
>
> ovn_datapath_add_router_port(op->od, op);
> + ovn_datapath_add_ls_peer(peer->od, op->od);
> peer->peer = op;
> op->peer = peer;
>
> @@ -3914,7 +3926,7 @@ build_lbs(struct northd_input *input_data, struct hmap
> *datapaths,
> nbrec_lb_group = od->nbs->load_balancer_group[i];
> lb_group = ovn_lb_group_find(lb_groups,
> &nbrec_lb_group->header_.uuid);
> - ovn_lb_group_add_ls(lb_group, od);
> + ovn_lb_group_add_ls(lb_group, 1, &od);
> }
> }
>
> @@ -4122,7 +4134,8 @@ build_lrouter_lbs_reachable_ips(struct hmap *datapaths,
> struct hmap *lbs,
> }
>
> static void
> -build_lswitch_lbs_from_lrouter(struct hmap *datapaths, struct hmap *lbs)
> +build_lswitch_lbs_from_lrouter(struct hmap *datapaths, struct hmap *lbs,
> + struct hmap *lb_groups)
> {
> if (!install_ls_lb_from_router) {
> return;
> @@ -4130,41 +4143,32 @@ build_lswitch_lbs_from_lrouter(struct hmap
> *datapaths, struct hmap *lbs)
>
> struct ovn_datapath *od;
> HMAP_FOR_EACH (od, key_node, datapaths) {
> - if (!od->nbs) {
> + if (!od->nbr) {
> continue;
> }
>
> - struct ovn_port *op;
> - LIST_FOR_EACH (op, dp_node, &od->port_list) {
> - if (!lsp_is_router(op->nbsp)) {
> - continue;
> + for (size_t i = 0; i < od->nbr->n_load_balancer; i++) {
> + const struct uuid *lb_uuid =
> + &od->nbr->load_balancer[i]->header_.uuid;
> + struct ovn_northd_lb *lb = ovn_northd_lb_find(lbs, lb_uuid);
We can avoid this lookup if instead we iterate over load balancers
first. That is:
foreach LB:
foreach LR in LB.nb_lr:
ovn_northd_lb_add_ls(LB, LR->n_ls_peers, LR->ls_peers);
> + if (lb) {
> + ovn_northd_lb_add_ls(lb, od->n_ls_peers, od->ls_peers);
> }
> - if (!op->peer) {
> + }
> +
> + for (size_t i = 0; i < od->nbr->n_load_balancer_group; i++) {
> + const struct nbrec_load_balancer_group *nbrec_lb_group
> + = od->nbr->load_balancer_group[i];
> + struct ovn_lb_group *lb_group =
> + ovn_lb_group_find(lb_groups, &nbrec_lb_group->header_.uuid);
Here too we can:
foreach LBG:
foreach LR in LBG.nb_lr:
ovn_lb_group_add_ls(LBG, LR->n_ls_peers, LR->ls_peers);
foreach LB in LBG:
ovn_northd_lb_add_ls(LB, LR->n_ls_peers, LR->ls_peers);
Regards,
Dumitru
> + if (!lb_group) {
> continue;
> }
>
> - struct ovn_datapath *peer_od = op->peer->od;
> - for (size_t i = 0; i < peer_od->nbr->n_load_balancer; i++) {
> - bool installed = false;
> - const struct uuid *lb_uuid =
> - &peer_od->nbr->load_balancer[i]->header_.uuid;
> - struct ovn_northd_lb *lb = ovn_northd_lb_find(lbs, lb_uuid);
> - if (!lb) {
> - continue;
> - }
> -
> - for (size_t j = 0; j < lb->n_nb_ls; j++) {
> - if (lb->nb_ls[j] == od) {
> - installed = true;
> - break;
> - }
> - }
> - if (!installed) {
> - ovn_northd_lb_add_ls(lb, 1, &od);
> - }
> - if (lb->nlb) {
> - od->has_lb_vip |= lb_has_vip(lb->nlb);
> - }
> + ovn_lb_group_add_ls(lb_group, od->n_ls_peers, od->ls_peers);
> + for (size_t j = 0; j < lb_group->n_lbs; j++) {
> + ovn_northd_lb_add_ls(lb_group->lbs[j], od->n_ls_peers,
> + od->ls_peers);
> }
> }
> }
> @@ -4183,7 +4187,7 @@ build_lb_port_related_data(struct hmap *datapaths,
> struct hmap *ports,
> build_lrouter_lbs_check(datapaths);
> build_lrouter_lbs_reachable_ips(datapaths, lbs, lb_groups);
> build_lb_svcs(input_data, ovnsb_txn, ports, lbs);
> - build_lswitch_lbs_from_lrouter(datapaths, lbs);
> + build_lswitch_lbs_from_lrouter(datapaths, lbs, lb_groups);
> }
>
>
> diff --git a/northd/northd.h b/northd/northd.h
> index 60601803f..da90e2815 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -191,6 +191,11 @@ struct ovn_datapath {
>
> uint32_t tunnel_key;
>
> + /* Logical router data. */
> + struct ovn_datapath **ls_peers;
> + size_t n_ls_peers;
> + size_t n_allocated_ls_peers;
> +
> /* Logical switch data. */
> struct ovn_port **router_ports;
> size_t n_router_ports;
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index bd6dad910..690f56526 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -7809,6 +7809,12 @@ ovn-nbctl lsp-set-options S1-R1 router-port=R1-S1
> ovn-nbctl lb-add lb0 172.16.0.10:80 10.0.0.2:80
> ovn-nbctl lr-lb-add R1 lb0
>
> +ovn-nbctl lb-add lb1 172.16.0.11:8080 10.0.0.2:8080
> +lb1_uuid=$(fetch_column nb:load_balancer _uuid name=lb1)
> +lbg=$(ovn-nbctl create load_balancer_group name=lbg -- \
> + add load_balancer_group lbg load_balancer $lb1_uuid)
> +ovn-nbctl add logical_router R1 load_balancer_group $lbg
> +
> ovn-sbctl dump-flows S0 > S0flows
> ovn-sbctl dump-flows S1 > S1flows
>
> @@ -7833,10 +7839,12 @@ AT_CAPTURE_FILE([S1flows])
> AT_CHECK([grep "ls_in_lb" S0flows | sort], [0], [dnl
> table=11(ls_in_lb ), priority=0 , match=(1), action=(next;)
> table=11(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst ==
> 172.16.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0;
> ct_lb_mark(backends=10.0.0.2:80);)
> + table=11(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst ==
> 172.16.0.11 && tcp.dst == 8080), action=(reg0[[1]] = 0;
> ct_lb_mark(backends=10.0.0.2:8080);)
> ])
> AT_CHECK([grep "ls_in_lb" S1flows | sort], [0], [dnl
> table=11(ls_in_lb ), priority=0 , match=(1), action=(next;)
> table=11(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst ==
> 172.16.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0;
> ct_lb_mark(backends=10.0.0.2:80);)
> + table=11(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst ==
> 172.16.0.11 && tcp.dst == 8080), action=(reg0[[1]] = 0;
> ct_lb_mark(backends=10.0.0.2:8080);)
> ])
>
> ovn-sbctl get datapath S0 _uuid > dp_uuids
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev