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

Reply via email to