diff mbox series

[ovs-dev,v5,10/16] northd: Move ovn_lb_datapaths from lib to northd module.

Message ID 20240111153222.2790366-1-numans@ovn.org
State Superseded
Headers show
Series northd lflow incremental processing | expand

Checks

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 fail github build: failed

Commit Message

Numan Siddique Jan. 11, 2024, 3:32 p.m. UTC
From: Numan Siddique <numans@ovn.org>

Signed-off-by: Numan Siddique <numans@ovn.org>
---
 lib/lb.c                |  96 -------------------------------
 lib/lb.h                |  57 -------------------
 northd/automake.mk      |   4 +-
 northd/en-lr-stateful.c |   1 +
 northd/lb.c             | 121 ++++++++++++++++++++++++++++++++++++++++
 northd/lb.h             |  82 +++++++++++++++++++++++++++
 northd/northd.c         |   1 +
 7 files changed, 208 insertions(+), 154 deletions(-)
 create mode 100644 northd/lb.c
 create mode 100644 northd/lb.h

Comments

Dumitru Ceara Jan. 19, 2024, 9:39 a.m. UTC | #1
On 1/11/24 16:32, numans@ovn.org wrote:
> From: Numan Siddique <numans@ovn.org>
> 
> Signed-off-by: Numan Siddique <numans@ovn.org>
> ---

In this case I think we should move all northd specific LB code from
lib/lb.c to northd/lb.c.  We should probably move all ovn-controller
specific LB code from lib/lb.c to a new controller/lb.c.

I tried that here:

https://github.com/dceara/ovn/commit/3f95e98a92828847ead8aa330702ea28b002590f

Feel free to use it if it looks OK to you too.

One more minor comment inline.

Thanks,
Dumitru

>  lib/lb.c                |  96 -------------------------------
>  lib/lb.h                |  57 -------------------
>  northd/automake.mk      |   4 +-
>  northd/en-lr-stateful.c |   1 +
>  northd/lb.c             | 121 ++++++++++++++++++++++++++++++++++++++++
>  northd/lb.h             |  82 +++++++++++++++++++++++++++
>  northd/northd.c         |   1 +
>  7 files changed, 208 insertions(+), 154 deletions(-)
>  create mode 100644 northd/lb.c
>  create mode 100644 northd/lb.h
> 
> diff --git a/lib/lb.c b/lib/lb.c
> index d0d562b6fb..991f20299d 100644
> --- a/lib/lb.c
> +++ b/lib/lb.c
> @@ -1071,99 +1071,3 @@ remove_ips_from_lb_ip_set(struct ovn_lb_ip_set *lb_ips,
>          }
>      }
>  }
> -
> -/* lb datapaths functions */
> -struct  ovn_lb_datapaths *
> -ovn_lb_datapaths_create(const struct ovn_northd_lb *lb, size_t n_ls_datapaths,
> -                        size_t n_lr_datapaths)
> -{
> -    struct ovn_lb_datapaths *lb_dps = xzalloc(sizeof *lb_dps);
> -    lb_dps->lb = lb;
> -    lb_dps->nb_ls_map = bitmap_allocate(n_ls_datapaths);
> -    lb_dps->nb_lr_map = bitmap_allocate(n_lr_datapaths);
> -
> -    return lb_dps;
> -}
> -
> -struct ovn_lb_datapaths *
> -ovn_lb_datapaths_find(const struct hmap *lb_dps_map,
> -                      const struct uuid *lb_uuid)
> -{
> -    struct ovn_lb_datapaths *lb_dps;
> -    size_t hash = uuid_hash(lb_uuid);
> -    HMAP_FOR_EACH_WITH_HASH (lb_dps, hmap_node, hash, lb_dps_map) {
> -        if (uuid_equals(&lb_dps->lb->nlb->header_.uuid, lb_uuid)) {
> -            return lb_dps;
> -        }
> -    }
> -    return NULL;
> -}
> -
> -void
> -ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *lb_dps)
> -{
> -    bitmap_free(lb_dps->nb_lr_map);
> -    bitmap_free(lb_dps->nb_ls_map);
> -    free(lb_dps);
> -}
> -
> -void
> -ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *lb_dps, size_t n,
> -                        struct ovn_datapath **ods)
> -{
> -    for (size_t i = 0; i < n; i++) {
> -        if (!bitmap_is_set(lb_dps->nb_lr_map, ods[i]->index)) {
> -            bitmap_set1(lb_dps->nb_lr_map, ods[i]->index);
> -            lb_dps->n_nb_lr++;
> -        }
> -    }
> -}
> -
> -void
> -ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *lb_dps, size_t n,
> -                        struct ovn_datapath **ods)
> -{
> -    for (size_t i = 0; i < n; i++) {
> -        if (!bitmap_is_set(lb_dps->nb_ls_map, ods[i]->index)) {
> -            bitmap_set1(lb_dps->nb_ls_map, ods[i]->index);
> -            lb_dps->n_nb_ls++;
> -        }
> -    }
> -}
> -
> -struct ovn_lb_group_datapaths *
> -ovn_lb_group_datapaths_create(const struct ovn_lb_group *lb_group,
> -                              size_t max_ls_datapaths,
> -                              size_t max_lr_datapaths)
> -{
> -    struct ovn_lb_group_datapaths *lb_group_dps =
> -        xzalloc(sizeof *lb_group_dps);
> -    lb_group_dps->lb_group = lb_group;
> -    lb_group_dps->ls = xmalloc(max_ls_datapaths * sizeof *lb_group_dps->ls);
> -    lb_group_dps->lr = xmalloc(max_lr_datapaths * sizeof *lb_group_dps->lr);
> -
> -    return lb_group_dps;
> -}
> -
> -void
> -ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *lb_group_dps)
> -{
> -    free(lb_group_dps->ls);
> -    free(lb_group_dps->lr);
> -    free(lb_group_dps);
> -}
> -
> -struct ovn_lb_group_datapaths *
> -ovn_lb_group_datapaths_find(const struct hmap *lb_group_dps_map,
> -                            const struct uuid *lb_group_uuid)
> -{
> -    struct ovn_lb_group_datapaths *lb_group_dps;
> -    size_t hash = uuid_hash(lb_group_uuid);
> -
> -    HMAP_FOR_EACH_WITH_HASH (lb_group_dps, hmap_node, hash, lb_group_dps_map) {
> -        if (uuid_equals(&lb_group_dps->lb_group->uuid, lb_group_uuid)) {
> -            return lb_group_dps;
> -        }
> -    }
> -    return NULL;
> -}
> diff --git a/lib/lb.h b/lib/lb.h
> index b8e3c1e8fb..90ac39ee5a 100644
> --- a/lib/lb.h
> +++ b/lib/lb.h
> @@ -167,63 +167,6 @@ void ovn_lb_group_reinit(
>      const struct nbrec_load_balancer_group *,
>      const struct hmap *lbs);
>  
> -struct ovn_lb_datapaths {
> -    struct hmap_node hmap_node;
> -
> -    const struct ovn_northd_lb *lb;
> -    size_t n_nb_ls;
> -    unsigned long *nb_ls_map;
> -
> -    size_t n_nb_lr;
> -    unsigned long *nb_lr_map;
> -};
> -
> -struct ovn_lb_datapaths *ovn_lb_datapaths_create(const struct ovn_northd_lb *,
> -                                                 size_t n_ls_datapaths,
> -                                                 size_t n_lr_datapaths);
> -struct ovn_lb_datapaths *ovn_lb_datapaths_find(const struct hmap *,
> -                                               const struct uuid *);
> -void ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *);
> -void ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *, size_t n,
> -                             struct ovn_datapath **);
> -void ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *, size_t n,
> -                             struct ovn_datapath **);
> -
> -struct ovn_lb_group_datapaths {
> -    struct hmap_node hmap_node;
> -
> -    const struct ovn_lb_group *lb_group;
> -
> -    /* Datapaths to which 'lb_group' is applied. */
> -    size_t n_ls;
> -    struct ovn_datapath **ls;
> -    size_t n_lr;
> -    struct ovn_datapath **lr;
> -};
> -
> -struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_create(
> -    const struct ovn_lb_group *, size_t max_ls_datapaths,
> -    size_t max_lr_datapaths);
> -
> -void ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *);
> -struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_find(
> -    const struct hmap *lb_group_dps, const struct uuid *);
> -
> -static inline void
> -ovn_lb_group_datapaths_add_ls(struct ovn_lb_group_datapaths *lbg_dps, size_t n,
> -                               struct ovn_datapath **ods)
> -{
> -    memcpy(&lbg_dps->ls[lbg_dps->n_ls], ods, n * sizeof *ods);
> -    lbg_dps->n_ls += n;
> -}
> -
> -static inline void
> -ovn_lb_group_datapaths_add_lr(struct ovn_lb_group_datapaths *lbg_dps,
> -                               struct ovn_datapath *lr)
> -{
> -    lbg_dps->lr[lbg_dps->n_lr++] = lr;
> -}
> -
>  struct ovn_controller_lb {
>      struct hmap_node hmap_node;
>  
> diff --git a/northd/automake.mk b/northd/automake.mk
> index 7c6d56a4ff..19abb0dece 100644
> --- a/northd/automake.mk
> +++ b/northd/automake.mk
> @@ -35,7 +35,9 @@ northd_ovn_northd_SOURCES = \
>  	northd/ipam.c \
>  	northd/ipam.h \
>  	northd/lflow-mgr.c \
> -	northd/lflow-mgr.h
> +	northd/lflow-mgr.h \
> +	northd/lb.c \
> +	northd/lb.h
>  northd_ovn_northd_LDADD = \
>  	lib/libovn.la \
>  	$(OVSDB_LIBDIR)/libovsdb.la \
> diff --git a/northd/en-lr-stateful.c b/northd/en-lr-stateful.c
> index 4287aaddc9..0c3b841050 100644
> --- a/northd/en-lr-stateful.c
> +++ b/northd/en-lr-stateful.c
> @@ -33,6 +33,7 @@
>  #include "en-lb-data.h"
>  #include "en-lr-nat.h"
>  #include "en-lr-stateful.h"
> +#include "lb.h"
>  #include "lib/inc-proc-eng.h"
>  #include "lib/lb.h"
>  #include "lib/ovn-nb-idl.h"
> diff --git a/northd/lb.c b/northd/lb.c
> new file mode 100644
> index 0000000000..e6c8a51911
> --- /dev/null
> +++ b/northd/lb.c
> @@ -0,0 +1,121 @@
> +/*
> + * Copyright (c) 2024, Red Hat, Inc.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +/* OVS includes */
> +#include "lib/bitmap.h"
> +
> +/* OVN includes */
> +#include "lb.h"
> +#include "lib/lb.h"
> +#include "northd.h"
> +
> +/* lb datapaths functions */
> +struct  ovn_lb_datapaths *
> +ovn_lb_datapaths_create(const struct ovn_northd_lb *lb, size_t n_ls_datapaths,
> +                        size_t n_lr_datapaths)
> +{
> +    struct ovn_lb_datapaths *lb_dps = xzalloc(sizeof *lb_dps);
> +    lb_dps->lb = lb;
> +    lb_dps->nb_ls_map = bitmap_allocate(n_ls_datapaths);
> +    lb_dps->nb_lr_map = bitmap_allocate(n_lr_datapaths);
> +
> +    return lb_dps;
> +}
> +
> +void
> +ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *lb_dps)
> +{
> +    bitmap_free(lb_dps->nb_lr_map);
> +    bitmap_free(lb_dps->nb_ls_map);
> +    free(lb_dps);
> +}
> +
> +void
> +ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *lb_dps, size_t n,
> +                        struct ovn_datapath **ods)
> +{
> +    for (size_t i = 0; i < n; i++) {
> +        if (!bitmap_is_set(lb_dps->nb_lr_map, ods[i]->index)) {
> +            bitmap_set1(lb_dps->nb_lr_map, ods[i]->index);
> +            lb_dps->n_nb_lr++;
> +        }
> +    }
> +}
> +
> +void
> +ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *lb_dps, size_t n,
> +                        struct ovn_datapath **ods)
> +{
> +    for (size_t i = 0; i < n; i++) {
> +        if (!bitmap_is_set(lb_dps->nb_ls_map, ods[i]->index)) {
> +            bitmap_set1(lb_dps->nb_ls_map, ods[i]->index);
> +            lb_dps->n_nb_ls++;
> +        }
> +    }
> +}
> +
> +struct ovn_lb_datapaths *
> +ovn_lb_datapaths_find(const struct hmap *lb_dps_map,
> +                      const struct uuid *lb_uuid)
> +{
> +    struct ovn_lb_datapaths *lb_dps;
> +    size_t hash = uuid_hash(lb_uuid);
> +    HMAP_FOR_EACH_WITH_HASH (lb_dps, hmap_node, hash, lb_dps_map) {
> +        if (uuid_equals(&lb_dps->lb->nlb->header_.uuid, lb_uuid)) {
> +            return lb_dps;
> +        }
> +    }
> +    return NULL;
> +}
> +
> +struct ovn_lb_group_datapaths *
> +ovn_lb_group_datapaths_create(const struct ovn_lb_group *lb_group,
> +                              size_t max_ls_datapaths,
> +                              size_t max_lr_datapaths)
> +{
> +    struct ovn_lb_group_datapaths *lb_group_dps =
> +        xzalloc(sizeof *lb_group_dps);
> +    lb_group_dps->lb_group = lb_group;
> +    lb_group_dps->ls = xmalloc(max_ls_datapaths * sizeof *lb_group_dps->ls);
> +    lb_group_dps->lr = xmalloc(max_lr_datapaths * sizeof *lb_group_dps->lr);
> +
> +    return lb_group_dps;
> +}
> +
> +void
> +ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *lb_group_dps)
> +{
> +    free(lb_group_dps->ls);
> +    free(lb_group_dps->lr);
> +    free(lb_group_dps);
> +}
> +
> +struct ovn_lb_group_datapaths *
> +ovn_lb_group_datapaths_find(const struct hmap *lb_group_dps_map,
> +                            const struct uuid *lb_group_uuid)
> +{
> +    struct ovn_lb_group_datapaths *lb_group_dps;
> +    size_t hash = uuid_hash(lb_group_uuid);
> +
> +    HMAP_FOR_EACH_WITH_HASH (lb_group_dps, hmap_node, hash, lb_group_dps_map) {
> +        if (uuid_equals(&lb_group_dps->lb_group->uuid, lb_group_uuid)) {
> +            return lb_group_dps;
> +        }
> +    }
> +    return NULL;
> +}
> diff --git a/northd/lb.h b/northd/lb.h
> new file mode 100644
> index 0000000000..eeef2ea260
> --- /dev/null
> +++ b/northd/lb.h
> @@ -0,0 +1,82 @@
> +/*
> + * Copyright (c) 2024, Red Hat, Inc.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#ifndef OVN_NORTHD_LB_H
> +#define OVN_NORTHD_LB_H 1
> +
> +#include "openvswitch/hmap.h"
> +#include "uuid.h"

This should include "lib/lb.h".

> +
> +struct ovn_lb_datapaths {
> +    struct hmap_node hmap_node;
> +
> +    const struct ovn_northd_lb *lb;
> +    size_t n_nb_ls;
> +    unsigned long *nb_ls_map;
> +
> +    size_t n_nb_lr;
> +    unsigned long *nb_lr_map;
> +};
> +
> +struct ovn_lb_datapaths *ovn_lb_datapaths_create(const struct ovn_northd_lb *,
> +                                                 size_t n_ls_datapaths,
> +                                                 size_t n_lr_datapaths);
> +struct ovn_lb_datapaths *ovn_lb_datapaths_find(const struct hmap *,
> +                                               const struct uuid *);
> +void ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *);
> +
> +struct ovn_datapath;
> +void ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *, size_t n,
> +                             struct ovn_datapath **);
> +void ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *, size_t n,
> +                             struct ovn_datapath **);
> +
> +struct ovn_lb_group_datapaths {
> +    struct hmap_node hmap_node;
> +
> +    const struct ovn_lb_group *lb_group;
> +
> +    /* Datapaths to which 'lb_group' is applied. */
> +    size_t n_ls;
> +    struct ovn_datapath **ls;
> +    size_t n_lr;
> +    struct ovn_datapath **lr;
> +};
> +
> +struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_create(
> +    const struct ovn_lb_group *, size_t max_ls_datapaths,
> +    size_t max_lr_datapaths);
> +
> +void ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *);
> +struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_find(
> +    const struct hmap *lb_group_dps, const struct uuid *);
> +
> +static inline void
> +ovn_lb_group_datapaths_add_ls(struct ovn_lb_group_datapaths *lbg_dps, size_t n,
> +                               struct ovn_datapath **ods)
> +{
> +    memcpy(&lbg_dps->ls[lbg_dps->n_ls], ods, n * sizeof *ods);
> +    lbg_dps->n_ls += n;
> +}
> +
> +static inline void
> +ovn_lb_group_datapaths_add_lr(struct ovn_lb_group_datapaths *lbg_dps,
> +                               struct ovn_datapath *lr)
> +{
> +    lbg_dps->lr[lbg_dps->n_lr++] = lr;
> +}
> +
> +#endif /* OVN_NORTHD_LB_H */
> \ No newline at end of file
> diff --git a/northd/northd.c b/northd/northd.c
> index a9cb0b6267..08732abbfa 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -31,6 +31,7 @@
>  #include "openvswitch/hmap.h"
>  #include "openvswitch/json.h"
>  #include "ovn/lex.h"
> +#include "lb.h"
>  #include "lib/chassis-index.h"
>  #include "lib/ip-mcast-index.h"
>  #include "lib/static-mac-binding-index.h"
diff mbox series

Patch

diff --git a/lib/lb.c b/lib/lb.c
index d0d562b6fb..991f20299d 100644
--- a/lib/lb.c
+++ b/lib/lb.c
@@ -1071,99 +1071,3 @@  remove_ips_from_lb_ip_set(struct ovn_lb_ip_set *lb_ips,
         }
     }
 }
-
-/* lb datapaths functions */
-struct  ovn_lb_datapaths *
-ovn_lb_datapaths_create(const struct ovn_northd_lb *lb, size_t n_ls_datapaths,
-                        size_t n_lr_datapaths)
-{
-    struct ovn_lb_datapaths *lb_dps = xzalloc(sizeof *lb_dps);
-    lb_dps->lb = lb;
-    lb_dps->nb_ls_map = bitmap_allocate(n_ls_datapaths);
-    lb_dps->nb_lr_map = bitmap_allocate(n_lr_datapaths);
-
-    return lb_dps;
-}
-
-struct ovn_lb_datapaths *
-ovn_lb_datapaths_find(const struct hmap *lb_dps_map,
-                      const struct uuid *lb_uuid)
-{
-    struct ovn_lb_datapaths *lb_dps;
-    size_t hash = uuid_hash(lb_uuid);
-    HMAP_FOR_EACH_WITH_HASH (lb_dps, hmap_node, hash, lb_dps_map) {
-        if (uuid_equals(&lb_dps->lb->nlb->header_.uuid, lb_uuid)) {
-            return lb_dps;
-        }
-    }
-    return NULL;
-}
-
-void
-ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *lb_dps)
-{
-    bitmap_free(lb_dps->nb_lr_map);
-    bitmap_free(lb_dps->nb_ls_map);
-    free(lb_dps);
-}
-
-void
-ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *lb_dps, size_t n,
-                        struct ovn_datapath **ods)
-{
-    for (size_t i = 0; i < n; i++) {
-        if (!bitmap_is_set(lb_dps->nb_lr_map, ods[i]->index)) {
-            bitmap_set1(lb_dps->nb_lr_map, ods[i]->index);
-            lb_dps->n_nb_lr++;
-        }
-    }
-}
-
-void
-ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *lb_dps, size_t n,
-                        struct ovn_datapath **ods)
-{
-    for (size_t i = 0; i < n; i++) {
-        if (!bitmap_is_set(lb_dps->nb_ls_map, ods[i]->index)) {
-            bitmap_set1(lb_dps->nb_ls_map, ods[i]->index);
-            lb_dps->n_nb_ls++;
-        }
-    }
-}
-
-struct ovn_lb_group_datapaths *
-ovn_lb_group_datapaths_create(const struct ovn_lb_group *lb_group,
-                              size_t max_ls_datapaths,
-                              size_t max_lr_datapaths)
-{
-    struct ovn_lb_group_datapaths *lb_group_dps =
-        xzalloc(sizeof *lb_group_dps);
-    lb_group_dps->lb_group = lb_group;
-    lb_group_dps->ls = xmalloc(max_ls_datapaths * sizeof *lb_group_dps->ls);
-    lb_group_dps->lr = xmalloc(max_lr_datapaths * sizeof *lb_group_dps->lr);
-
-    return lb_group_dps;
-}
-
-void
-ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *lb_group_dps)
-{
-    free(lb_group_dps->ls);
-    free(lb_group_dps->lr);
-    free(lb_group_dps);
-}
-
-struct ovn_lb_group_datapaths *
-ovn_lb_group_datapaths_find(const struct hmap *lb_group_dps_map,
-                            const struct uuid *lb_group_uuid)
-{
-    struct ovn_lb_group_datapaths *lb_group_dps;
-    size_t hash = uuid_hash(lb_group_uuid);
-
-    HMAP_FOR_EACH_WITH_HASH (lb_group_dps, hmap_node, hash, lb_group_dps_map) {
-        if (uuid_equals(&lb_group_dps->lb_group->uuid, lb_group_uuid)) {
-            return lb_group_dps;
-        }
-    }
-    return NULL;
-}
diff --git a/lib/lb.h b/lib/lb.h
index b8e3c1e8fb..90ac39ee5a 100644
--- a/lib/lb.h
+++ b/lib/lb.h
@@ -167,63 +167,6 @@  void ovn_lb_group_reinit(
     const struct nbrec_load_balancer_group *,
     const struct hmap *lbs);
 
-struct ovn_lb_datapaths {
-    struct hmap_node hmap_node;
-
-    const struct ovn_northd_lb *lb;
-    size_t n_nb_ls;
-    unsigned long *nb_ls_map;
-
-    size_t n_nb_lr;
-    unsigned long *nb_lr_map;
-};
-
-struct ovn_lb_datapaths *ovn_lb_datapaths_create(const struct ovn_northd_lb *,
-                                                 size_t n_ls_datapaths,
-                                                 size_t n_lr_datapaths);
-struct ovn_lb_datapaths *ovn_lb_datapaths_find(const struct hmap *,
-                                               const struct uuid *);
-void ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *);
-void ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *, size_t n,
-                             struct ovn_datapath **);
-void ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *, size_t n,
-                             struct ovn_datapath **);
-
-struct ovn_lb_group_datapaths {
-    struct hmap_node hmap_node;
-
-    const struct ovn_lb_group *lb_group;
-
-    /* Datapaths to which 'lb_group' is applied. */
-    size_t n_ls;
-    struct ovn_datapath **ls;
-    size_t n_lr;
-    struct ovn_datapath **lr;
-};
-
-struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_create(
-    const struct ovn_lb_group *, size_t max_ls_datapaths,
-    size_t max_lr_datapaths);
-
-void ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *);
-struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_find(
-    const struct hmap *lb_group_dps, const struct uuid *);
-
-static inline void
-ovn_lb_group_datapaths_add_ls(struct ovn_lb_group_datapaths *lbg_dps, size_t n,
-                               struct ovn_datapath **ods)
-{
-    memcpy(&lbg_dps->ls[lbg_dps->n_ls], ods, n * sizeof *ods);
-    lbg_dps->n_ls += n;
-}
-
-static inline void
-ovn_lb_group_datapaths_add_lr(struct ovn_lb_group_datapaths *lbg_dps,
-                               struct ovn_datapath *lr)
-{
-    lbg_dps->lr[lbg_dps->n_lr++] = lr;
-}
-
 struct ovn_controller_lb {
     struct hmap_node hmap_node;
 
diff --git a/northd/automake.mk b/northd/automake.mk
index 7c6d56a4ff..19abb0dece 100644
--- a/northd/automake.mk
+++ b/northd/automake.mk
@@ -35,7 +35,9 @@  northd_ovn_northd_SOURCES = \
 	northd/ipam.c \
 	northd/ipam.h \
 	northd/lflow-mgr.c \
-	northd/lflow-mgr.h
+	northd/lflow-mgr.h \
+	northd/lb.c \
+	northd/lb.h
 northd_ovn_northd_LDADD = \
 	lib/libovn.la \
 	$(OVSDB_LIBDIR)/libovsdb.la \
diff --git a/northd/en-lr-stateful.c b/northd/en-lr-stateful.c
index 4287aaddc9..0c3b841050 100644
--- a/northd/en-lr-stateful.c
+++ b/northd/en-lr-stateful.c
@@ -33,6 +33,7 @@ 
 #include "en-lb-data.h"
 #include "en-lr-nat.h"
 #include "en-lr-stateful.h"
+#include "lb.h"
 #include "lib/inc-proc-eng.h"
 #include "lib/lb.h"
 #include "lib/ovn-nb-idl.h"
diff --git a/northd/lb.c b/northd/lb.c
new file mode 100644
index 0000000000..e6c8a51911
--- /dev/null
+++ b/northd/lb.c
@@ -0,0 +1,121 @@ 
+/*
+ * Copyright (c) 2024, Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+/* OVS includes */
+#include "lib/bitmap.h"
+
+/* OVN includes */
+#include "lb.h"
+#include "lib/lb.h"
+#include "northd.h"
+
+/* lb datapaths functions */
+struct  ovn_lb_datapaths *
+ovn_lb_datapaths_create(const struct ovn_northd_lb *lb, size_t n_ls_datapaths,
+                        size_t n_lr_datapaths)
+{
+    struct ovn_lb_datapaths *lb_dps = xzalloc(sizeof *lb_dps);
+    lb_dps->lb = lb;
+    lb_dps->nb_ls_map = bitmap_allocate(n_ls_datapaths);
+    lb_dps->nb_lr_map = bitmap_allocate(n_lr_datapaths);
+
+    return lb_dps;
+}
+
+void
+ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *lb_dps)
+{
+    bitmap_free(lb_dps->nb_lr_map);
+    bitmap_free(lb_dps->nb_ls_map);
+    free(lb_dps);
+}
+
+void
+ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *lb_dps, size_t n,
+                        struct ovn_datapath **ods)
+{
+    for (size_t i = 0; i < n; i++) {
+        if (!bitmap_is_set(lb_dps->nb_lr_map, ods[i]->index)) {
+            bitmap_set1(lb_dps->nb_lr_map, ods[i]->index);
+            lb_dps->n_nb_lr++;
+        }
+    }
+}
+
+void
+ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *lb_dps, size_t n,
+                        struct ovn_datapath **ods)
+{
+    for (size_t i = 0; i < n; i++) {
+        if (!bitmap_is_set(lb_dps->nb_ls_map, ods[i]->index)) {
+            bitmap_set1(lb_dps->nb_ls_map, ods[i]->index);
+            lb_dps->n_nb_ls++;
+        }
+    }
+}
+
+struct ovn_lb_datapaths *
+ovn_lb_datapaths_find(const struct hmap *lb_dps_map,
+                      const struct uuid *lb_uuid)
+{
+    struct ovn_lb_datapaths *lb_dps;
+    size_t hash = uuid_hash(lb_uuid);
+    HMAP_FOR_EACH_WITH_HASH (lb_dps, hmap_node, hash, lb_dps_map) {
+        if (uuid_equals(&lb_dps->lb->nlb->header_.uuid, lb_uuid)) {
+            return lb_dps;
+        }
+    }
+    return NULL;
+}
+
+struct ovn_lb_group_datapaths *
+ovn_lb_group_datapaths_create(const struct ovn_lb_group *lb_group,
+                              size_t max_ls_datapaths,
+                              size_t max_lr_datapaths)
+{
+    struct ovn_lb_group_datapaths *lb_group_dps =
+        xzalloc(sizeof *lb_group_dps);
+    lb_group_dps->lb_group = lb_group;
+    lb_group_dps->ls = xmalloc(max_ls_datapaths * sizeof *lb_group_dps->ls);
+    lb_group_dps->lr = xmalloc(max_lr_datapaths * sizeof *lb_group_dps->lr);
+
+    return lb_group_dps;
+}
+
+void
+ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *lb_group_dps)
+{
+    free(lb_group_dps->ls);
+    free(lb_group_dps->lr);
+    free(lb_group_dps);
+}
+
+struct ovn_lb_group_datapaths *
+ovn_lb_group_datapaths_find(const struct hmap *lb_group_dps_map,
+                            const struct uuid *lb_group_uuid)
+{
+    struct ovn_lb_group_datapaths *lb_group_dps;
+    size_t hash = uuid_hash(lb_group_uuid);
+
+    HMAP_FOR_EACH_WITH_HASH (lb_group_dps, hmap_node, hash, lb_group_dps_map) {
+        if (uuid_equals(&lb_group_dps->lb_group->uuid, lb_group_uuid)) {
+            return lb_group_dps;
+        }
+    }
+    return NULL;
+}
diff --git a/northd/lb.h b/northd/lb.h
new file mode 100644
index 0000000000..eeef2ea260
--- /dev/null
+++ b/northd/lb.h
@@ -0,0 +1,82 @@ 
+/*
+ * Copyright (c) 2024, Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVN_NORTHD_LB_H
+#define OVN_NORTHD_LB_H 1
+
+#include "openvswitch/hmap.h"
+#include "uuid.h"
+
+struct ovn_lb_datapaths {
+    struct hmap_node hmap_node;
+
+    const struct ovn_northd_lb *lb;
+    size_t n_nb_ls;
+    unsigned long *nb_ls_map;
+
+    size_t n_nb_lr;
+    unsigned long *nb_lr_map;
+};
+
+struct ovn_lb_datapaths *ovn_lb_datapaths_create(const struct ovn_northd_lb *,
+                                                 size_t n_ls_datapaths,
+                                                 size_t n_lr_datapaths);
+struct ovn_lb_datapaths *ovn_lb_datapaths_find(const struct hmap *,
+                                               const struct uuid *);
+void ovn_lb_datapaths_destroy(struct ovn_lb_datapaths *);
+
+struct ovn_datapath;
+void ovn_lb_datapaths_add_lr(struct ovn_lb_datapaths *, size_t n,
+                             struct ovn_datapath **);
+void ovn_lb_datapaths_add_ls(struct ovn_lb_datapaths *, size_t n,
+                             struct ovn_datapath **);
+
+struct ovn_lb_group_datapaths {
+    struct hmap_node hmap_node;
+
+    const struct ovn_lb_group *lb_group;
+
+    /* Datapaths to which 'lb_group' is applied. */
+    size_t n_ls;
+    struct ovn_datapath **ls;
+    size_t n_lr;
+    struct ovn_datapath **lr;
+};
+
+struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_create(
+    const struct ovn_lb_group *, size_t max_ls_datapaths,
+    size_t max_lr_datapaths);
+
+void ovn_lb_group_datapaths_destroy(struct ovn_lb_group_datapaths *);
+struct ovn_lb_group_datapaths *ovn_lb_group_datapaths_find(
+    const struct hmap *lb_group_dps, const struct uuid *);
+
+static inline void
+ovn_lb_group_datapaths_add_ls(struct ovn_lb_group_datapaths *lbg_dps, size_t n,
+                               struct ovn_datapath **ods)
+{
+    memcpy(&lbg_dps->ls[lbg_dps->n_ls], ods, n * sizeof *ods);
+    lbg_dps->n_ls += n;
+}
+
+static inline void
+ovn_lb_group_datapaths_add_lr(struct ovn_lb_group_datapaths *lbg_dps,
+                               struct ovn_datapath *lr)
+{
+    lbg_dps->lr[lbg_dps->n_lr++] = lr;
+}
+
+#endif /* OVN_NORTHD_LB_H */
\ No newline at end of file
diff --git a/northd/northd.c b/northd/northd.c
index a9cb0b6267..08732abbfa 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -31,6 +31,7 @@ 
 #include "openvswitch/hmap.h"
 #include "openvswitch/json.h"
 #include "ovn/lex.h"
+#include "lb.h"
 #include "lib/chassis-index.h"
 #include "lib/ip-mcast-index.h"
 #include "lib/static-mac-binding-index.h"