> To make the code more readable and make future changes easier we split
> the main logic of join_logical_ports to separate functions for LSPs and
> LRPs.
> 
> Signed-off-by: Felix Huettner <felix.huettner@stackit.cloud>

Acked-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com>

> ---
>  northd/northd.c | 321 ++++++++++++++++++++++++++----------------------
>  northd/northd.h |   1 +
>  2 files changed, 176 insertions(+), 146 deletions(-)
> 
> diff --git a/northd/northd.c b/northd/northd.c
> index b208a3617..8d95650c2 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -2127,6 +2127,175 @@ parse_lsp_addrs(struct ovn_port *op)
>          op->n_ps_addrs++;
>      }
>  }
> +static struct ovn_port *
> +join_logical_ports_lsp(struct hmap *ports,
> +                       struct ovs_list *nb_only, struct ovs_list *both,
> +                       struct ovn_datapath *od,
> +                       const struct nbrec_logical_switch_port *nbsp,
> +                       const char *name,
> +                       unsigned long *queue_id_bitmap,
> +                       struct hmap *tag_alloc_table)
> +{
> +    struct ovn_port *op = ovn_port_find_bound(ports, name);
> +    if (op && (op->od || op->nbsp || op->nbrp)) {
> +        static struct vlog_rate_limit rl
> +            = VLOG_RATE_LIMIT_INIT(5, 1);
> +        VLOG_WARN_RL(&rl, "duplicate logical port %s", name);
> +        return NULL;
> +    } else if (op && (!op->sb || op->sb->datapath == od->sb)) {
> +        /*
> +         * Handle cases where lport type was explicitly changed
> +         * in the NBDB, in such cases:
> +         * 1. remove the current sbrec of the affected lport from
> +         *    the port_binding table.
> +         *
> +         * 2. create a new sbrec with the same logical_port as the
> +         *    deleted lport and add it to the nb_only list which
> +         *    will make the northd handle this lport as a new
> +         *    created one and recompute everything that is needed
> +         *    for this lport.
> +         *
> +         * This change will affect container/virtual lport type
> +         * changes only for now, this change is needed in
> +         * contaier/virtual lport cases to avoid port type
> +         * conflicts in the ovn-controller when the user clears
> +         * the parent_port field in the container lport or updated
> +         * the lport type.
> +         *
> +         */
> +        bool update_sbrec = false;
> +        if (op->sb && lsp_is_type_changed(op->sb, nbsp,
> +                                          &update_sbrec)
> +                       && update_sbrec) {
> +            ovs_list_remove(&op->list);
> +            sbrec_port_binding_delete(op->sb);
> +            ovn_port_destroy(ports, op);
> +            op = ovn_port_create(ports, name, nbsp,
> +                                 NULL, NULL);
> +            ovs_list_push_back(nb_only, &op->list);
> +        } else {
> +            ovn_port_set_nb(op, nbsp, NULL);
> +            ovs_list_remove(&op->list);
> +
> +            uint32_t queue_id = smap_get_int(&op->sb->options,
> +                                             "qdisc_queue_id", 0);
> +            if (queue_id) {
> +                bitmap_set1(queue_id_bitmap, queue_id);
> +            }
> +
> +            ovs_list_push_back(both, &op->list);
> +
> +            /* This port exists due to a SB binding, but should
> +             * not have been initialized fully. */
> +            ovs_assert(!op->n_lsp_addrs && !op->n_ps_addrs);
> +        }
> +    } else {
> +        op = ovn_port_create(ports, name, nbsp, NULL, NULL);
> +        ovs_list_push_back(nb_only, &op->list);
> +    }
> +
> +    if (lsp_is_localnet(nbsp)) {
> +       if (od->n_localnet_ports >= od->n_allocated_localnet_ports) {
> +           od->localnet_ports = x2nrealloc(
> +               od->localnet_ports, &od->n_allocated_localnet_ports,
> +               sizeof *od->localnet_ports);
> +       }
> +       od->localnet_ports[od->n_localnet_ports++] = op;
> +    }
> +
> +    if (lsp_is_vtep(nbsp)) {
> +        od->has_vtep_lports = true;
> +    }
> +
> +    parse_lsp_addrs(op);
> +
> +    op->od = od;
> +    if (op->has_unknown) {
> +        od->has_unknown = true;
> +    }
> +    hmap_insert(&od->ports, &op->dp_node,
> +                hmap_node_hash(&op->key_node));
> +    tag_alloc_add_existing_tags(tag_alloc_table, nbsp);
> +    return op;
> +}
> +
> +static struct ovn_port*
> +join_logical_ports_lrp(struct hmap *ports,
> +                       struct ovs_list *nb_only, struct ovs_list *both,
> +                       struct hmapx *dgps,
> +                       struct ovn_datapath *od,
> +                       const struct nbrec_logical_router_port *nbrp,
> +                       const char *name, struct lport_addresses 
> *lrp_networks)
> +{
> +    if (!lrp_networks->n_ipv4_addrs && !lrp_networks->n_ipv6_addrs) {
> +      return NULL;
> +    }
> +
> +    struct ovn_port *op = ovn_port_find_bound(ports, name);
> +    if (op && (op->od || op->nbsp || op->nbrp)) {
> +        static struct vlog_rate_limit rl
> +            = VLOG_RATE_LIMIT_INIT(5, 1);
> +        VLOG_WARN_RL(&rl, "duplicate logical router port %s",
> +                     name);
> +        destroy_lport_addresses(lrp_networks);
> +        return NULL;
> +    } else if (op && (!op->sb || op->sb->datapath == od->sb)) {
> +        ovn_port_set_nb(op, NULL, nbrp);
> +        ovs_list_remove(&op->list);
> +        ovs_list_push_back(both, &op->list);
> +
> +        /* This port exists but should not have been
> +         * initialized fully. */
> +        ovs_assert(!op->lrp_networks.n_ipv4_addrs
> +                   && !op->lrp_networks.n_ipv6_addrs);
> +    } else {
> +        op = ovn_port_create(ports, name, NULL, nbrp, NULL);
> +        ovs_list_push_back(nb_only, &op->list);
> +    }
> +
> +    op->lrp_networks = *lrp_networks;
> +    op->od = od;
> +
> +    for (size_t j = 0; j < op->lrp_networks.n_ipv4_addrs; j++) {
> +        sset_add(&op->od->router_ips,
> +                 op->lrp_networks.ipv4_addrs[j].addr_s);
> +    }
> +    for (size_t j = 0; j < op->lrp_networks.n_ipv6_addrs; j++) {
> +        /* Exclude the LLA. */
> +        if (!in6_is_lla(&op->lrp_networks.ipv6_addrs[j].addr)) {
> +            sset_add(&op->od->router_ips,
> +                     op->lrp_networks.ipv6_addrs[j].addr_s);
> +        }
> +    }
> +
> +    hmap_insert(&od->ports, &op->dp_node,
> +                hmap_node_hash(&op->key_node));
> +
> +    if (!od->redirect_bridged) {
> +        const char *redirect_type =
> +            smap_get(&nbrp->options, "redirect-type");
> +        od->redirect_bridged =
> +            redirect_type && !strcasecmp(redirect_type, "bridged");
> +    }
> +
> +    if (op->nbrp->ha_chassis_group || op->nbrp->n_gateway_chassis) {
> +        const char *gw_chassis = smap_get(&op->od->nbr->options,
> +                                       "chassis");
> +        if (gw_chassis) {
> +            static struct vlog_rate_limit rl
> +                = VLOG_RATE_LIMIT_INIT(1, 1);
> +            VLOG_WARN_RL(&rl, "Bad configuration: distributed "
> +                         "gateway port configured on port %s "
> +                         "on L3 gateway router", name);
> +            return NULL;
> +        } else {
> +            hmapx_add(dgps, op);
> +        }
> +
> +    }
> +    return op;
> +}
> +
>  
>  static struct ovn_port *
>  create_cr_port(struct ovn_port *op, struct hmap *ports,
> @@ -2198,90 +2367,12 @@ join_logical_ports(const struct 
> sbrec_port_binding_table *sbrec_pb_table,
>      struct ovn_datapath *od;
>      HMAP_FOR_EACH (od, key_node, ls_datapaths) {
>          ovs_assert(od->nbs);
> -        size_t n_allocated_localnet_ports = 0;
>          for (size_t i = 0; i < od->nbs->n_ports; i++) {
>              const struct nbrec_logical_switch_port *nbsp
>                  = od->nbs->ports[i];
> -            struct ovn_port *op = ovn_port_find_bound(ports, nbsp->name);
> -            if (op && (op->od || op->nbsp || op->nbrp)) {
> -                static struct vlog_rate_limit rl
> -                    = VLOG_RATE_LIMIT_INIT(5, 1);
> -                VLOG_WARN_RL(&rl, "duplicate logical port %s", nbsp->name);
> -                continue;
> -            } else if (op && (!op->sb || op->sb->datapath == od->sb)) {
> -                /*
> -                 * Handle cases where lport type was explicitly changed
> -                 * in the NBDB, in such cases:
> -                 * 1. remove the current sbrec of the affected lport from
> -                 *    the port_binding table.
> -                 *
> -                 * 2. create a new sbrec with the same logical_port as the
> -                 *    deleted lport and add it to the nb_only list which
> -                 *    will make the northd handle this lport as a new
> -                 *    created one and recompute everything that is needed
> -                 *    for this lport.
> -                 *
> -                 * This change will affect container/virtual lport type
> -                 * changes only for now, this change is needed in
> -                 * contaier/virtual lport cases to avoid port type
> -                 * conflicts in the ovn-controller when the user clears
> -                 * the parent_port field in the container lport or updated
> -                 * the lport type.
> -                 *
> -                 */
> -                bool update_sbrec = false;
> -                if (op->sb && lsp_is_type_changed(op->sb, nbsp,
> -                                                  &update_sbrec)
> -                               && update_sbrec) {
> -                    ovs_list_remove(&op->list);
> -                    sbrec_port_binding_delete(op->sb);
> -                    ovn_port_destroy(ports, op);
> -                    op = ovn_port_create(ports, nbsp->name, nbsp,
> -                                         NULL, NULL);
> -                    ovs_list_push_back(nb_only, &op->list);
> -                } else {
> -                    ovn_port_set_nb(op, nbsp, NULL);
> -                    ovs_list_remove(&op->list);
> -
> -                    uint32_t queue_id = smap_get_int(&op->sb->options,
> -                                                     "qdisc_queue_id", 0);
> -                    if (queue_id) {
> -                        bitmap_set1(queue_id_bitmap, queue_id);
> -                    }
> -
> -                    ovs_list_push_back(both, &op->list);
> -
> -                    /* This port exists due to a SB binding, but should
> -                     * not have been initialized fully. */
> -                    ovs_assert(!op->n_lsp_addrs && !op->n_ps_addrs);
> -                }
> -            } else {
> -                op = ovn_port_create(ports, nbsp->name, nbsp, NULL, NULL);
> -                ovs_list_push_back(nb_only, &op->list);
> -            }
> -
> -            if (lsp_is_localnet(nbsp)) {
> -               if (od->n_localnet_ports >= n_allocated_localnet_ports) {
> -                   od->localnet_ports = x2nrealloc(
> -                       od->localnet_ports, &n_allocated_localnet_ports,
> -                       sizeof *od->localnet_ports);
> -               }
> -               od->localnet_ports[od->n_localnet_ports++] = op;
> -            }
> -
> -            if (lsp_is_vtep(nbsp)) {
> -                od->has_vtep_lports = true;
> -            }
> -
> -            parse_lsp_addrs(op);
> -
> -            op->od = od;
> -            if (op->has_unknown) {
> -                od->has_unknown = true;
> -            }
> -            hmap_insert(&od->ports, &op->dp_node,
> -                        hmap_node_hash(&op->key_node));
> -            tag_alloc_add_existing_tags(tag_alloc_table, nbsp);
> +            join_logical_ports_lsp(ports, nb_only, both, od, nbsp,
> +                                   nbsp->name, queue_id_bitmap,
> +                                   tag_alloc_table);
>          }
>      }
>  
> @@ -2299,71 +2390,9 @@ join_logical_ports(const struct 
> sbrec_port_binding_table *sbrec_pb_table,
>                  VLOG_WARN_RL(&rl, "bad 'mac' %s", nbrp->mac);
>                  continue;
>              }
> -
> -            if (!lrp_networks.n_ipv4_addrs && !lrp_networks.n_ipv6_addrs) {
> -                continue;
> -            }
> -
> -            struct ovn_port *op = ovn_port_find_bound(ports, nbrp->name);
> -            if (op && (op->od || op->nbsp || op->nbrp)) {
> -                static struct vlog_rate_limit rl
> -                    = VLOG_RATE_LIMIT_INIT(5, 1);
> -                VLOG_WARN_RL(&rl, "duplicate logical router port %s",
> -                             nbrp->name);
> -                destroy_lport_addresses(&lrp_networks);
> -                continue;
> -            } else if (op && (!op->sb || op->sb->datapath == od->sb)) {
> -                ovn_port_set_nb(op, NULL, nbrp);
> -                ovs_list_remove(&op->list);
> -                ovs_list_push_back(both, &op->list);
> -
> -                /* This port exists but should not have been
> -                 * initialized fully. */
> -                ovs_assert(!op->lrp_networks.n_ipv4_addrs
> -                           && !op->lrp_networks.n_ipv6_addrs);
> -            } else {
> -                op = ovn_port_create(ports, nbrp->name, NULL, nbrp, NULL);
> -                ovs_list_push_back(nb_only, &op->list);
> -            }
> -
> -            op->lrp_networks = lrp_networks;
> -            op->od = od;
> -
> -            for (size_t j = 0; j < op->lrp_networks.n_ipv4_addrs; j++) {
> -                sset_add(&op->od->router_ips,
> -                         op->lrp_networks.ipv4_addrs[j].addr_s);
> -            }
> -            for (size_t j = 0; j < op->lrp_networks.n_ipv6_addrs; j++) {
> -                /* Exclude the LLA. */
> -                if (!in6_is_lla(&op->lrp_networks.ipv6_addrs[j].addr)) {
> -                    sset_add(&op->od->router_ips,
> -                             op->lrp_networks.ipv6_addrs[j].addr_s);
> -                }
> -            }
> -
> -            hmap_insert(&od->ports, &op->dp_node,
> -                        hmap_node_hash(&op->key_node));
> -
> -            if (!od->redirect_bridged) {
> -                const char *redirect_type =
> -                    smap_get(&nbrp->options, "redirect-type");
> -                od->redirect_bridged =
> -                    redirect_type && !strcasecmp(redirect_type, "bridged");
> -            }
> -
> -            if (op->nbrp->ha_chassis_group || op->nbrp->n_gateway_chassis) {
> -                const char *gw_chassis = smap_get(&op->od->nbr->options,
> -                                               "chassis");
> -                if (gw_chassis) {
> -                    static struct vlog_rate_limit rl
> -                        = VLOG_RATE_LIMIT_INIT(1, 1);
> -                    VLOG_WARN_RL(&rl, "Bad configuration: distributed "
> -                                 "gateway port configured on port %s "
> -                                 "on L3 gateway router", nbrp->name);
> -                } else {
> -                    hmapx_add(&dgps, op);
> -                }
> -           }
> +            join_logical_ports_lrp(ports, nb_only, both, &dgps,
> +                                   od, nbrp,
> +                                   nbrp->name, &lrp_networks);
>          }
>      }
>  
> diff --git a/northd/northd.h b/northd/northd.h
> index 728fa6740..665ff87bc 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -371,6 +371,7 @@ struct ovn_datapath {
>  
>      struct ovn_port **localnet_ports;
>      size_t n_localnet_ports;
> +    size_t n_allocated_localnet_ports;
>  
>      struct ovs_list lr_list; /* In list of logical router datapaths. */
>      /* The logical router group to which this datapath belongs.
> -- 
> 2.47.0
> 
> 
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> 
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to