There's currently no need to store both 'ovn_ls_port_group'
and 'ovn_port_group_ls' so just use the first type.

Signed-off-by: Dumitru Ceara <dce...@redhat.com>
---
 northd/en-lflow.c |    2 
 northd/northd.c   |  286 +++++++++++++++++++++++++----------------------------
 northd/northd.h   |   25 ++++-
 3 files changed, 158 insertions(+), 155 deletions(-)

diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index 28ab1c67fb..7187cf959f 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -55,7 +55,7 @@ lflow_get_input_data(struct engine_node *node,
     lflow_input->lr_datapaths = &northd_data->lr_datapaths;
     lflow_input->ls_ports = &northd_data->ls_ports;
     lflow_input->lr_ports = &northd_data->lr_ports;
-    lflow_input->port_groups = &northd_data->port_groups;
+    lflow_input->ls_port_groups = &northd_data->ls_port_groups;
     lflow_input->meter_groups = &northd_data->meter_groups;
     lflow_input->lbs = &northd_data->lbs;
     lflow_input->features = &northd_data->features;
diff --git a/northd/northd.c b/northd/northd.c
index 9a12a94ae2..73fab3af7e 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -813,7 +813,6 @@ ovn_datapath_create(struct hmap *datapaths, const struct 
uuid *key,
     od->nbs = nbs;
     od->nbr = nbr;
     hmap_init(&od->port_tnlids);
-    hmap_init(&od->nb_pgs);
     od->port_key_hint = 0;
     hmap_insert(datapaths, &od->key_node, uuid_hash(&od->key));
     od->lr_group = NULL;
@@ -821,7 +820,6 @@ ovn_datapath_create(struct hmap *datapaths, const struct 
uuid *key,
     return od;
 }
 
-static void ovn_ls_port_group_destroy(struct hmap *nb_pgs);
 static void destroy_mcast_info_for_datapath(struct ovn_datapath *od);
 
 static void
@@ -849,7 +847,6 @@ ovn_datapath_destroy(struct hmap *datapaths, struct 
ovn_datapath *od)
         free(od->nat_entries);
         free(od->localnet_ports);
         free(od->l3dgw_ports);
-        ovn_ls_port_group_destroy(&od->nb_pgs);
         destroy_mcast_info_for_datapath(od);
         destroy_ports_for_datapath(od);
 
@@ -6240,83 +6237,87 @@ build_dhcpv6_action(struct ovn_port *op, struct 
in6_addr *offer_ip,
     return true;
 }
 
-struct ovn_port_group_ls {
-    struct hmap_node key_node;  /* Index on 'key'. */
-    struct uuid key;            /* nb_ls->header_.uuid. */
-    struct ovn_datapath *od;
-
-    struct ovn_port **ports; /* Ports in 'od' referrenced by the PG. */
-    size_t n_ports;
-    size_t n_allocated_ports;
-};
-
-struct ovn_port_group {
-    struct hmap_node key_node;  /* Index on 'key'. */
-    struct uuid key;            /* nb_pg->header_.uuid. */
-    const struct nbrec_port_group *nb_pg;
-    struct hmap nb_lswitches;   /* NB lswitches related to the port group */
-};
-
-static struct ovn_port_group_ls *
-ovn_port_group_ls_add(struct ovn_port_group *pg, struct ovn_datapath *od)
+static struct ls_port_group_record *
+ls_port_group_record_add(struct hmap *nb_pgs,
+                         const struct nbrec_port_group *nb_pg,
+                         const char *port_name)
 {
-    struct ovn_port_group_ls *pg_ls = xzalloc(sizeof *pg_ls);
-    pg_ls->key = od->nbs->header_.uuid;
-    pg_ls->od = od;
-    hmap_insert(&pg->nb_lswitches, &pg_ls->key_node, uuid_hash(&pg_ls->key));
-    return pg_ls;
-}
+    struct ls_port_group_record *ls_pg_rec = NULL;
+    size_t hash = uuid_hash(&nb_pg->header_.uuid);
 
-static struct ovn_port_group_ls *
-ovn_port_group_ls_find(struct ovn_port_group *pg, const struct uuid *ls_uuid)
-{
-    struct ovn_port_group_ls *pg_ls;
-
-    HMAP_FOR_EACH_WITH_HASH (pg_ls, key_node, uuid_hash(ls_uuid),
-                             &pg->nb_lswitches) {
-        if (uuid_equals(ls_uuid, &pg_ls->key)) {
-            return pg_ls;
+    HMAP_FOR_EACH_WITH_HASH (ls_pg_rec, key_node, hash, nb_pgs) {
+        if (ls_pg_rec->nb_pg == nb_pg) {
+            goto done;
         }
     }
-    return NULL;
+
+    ls_pg_rec = xzalloc(sizeof *ls_pg_rec);
+    *ls_pg_rec = (struct ls_port_group_record) {
+        .nb_pg = nb_pg,
+        .ports = SSET_INITIALIZER(&ls_pg_rec->ports),
+    };
+    hmap_insert(nb_pgs, &ls_pg_rec->key_node, hash);
+done:
+    sset_add(&ls_pg_rec->ports, port_name);
+    return ls_pg_rec;
 }
 
 static void
-ovn_port_group_ls_add_port(struct ovn_port_group_ls *pg_ls,
-                           struct ovn_port *op)
+ls_port_group_record_destroy(struct hmap *nb_pgs,
+                             struct ls_port_group_record *ls_pg_rec)
 {
-    if (pg_ls->n_ports == pg_ls->n_allocated_ports) {
-        pg_ls->ports = x2nrealloc(pg_ls->ports,
-                                  &pg_ls->n_allocated_ports,
-                                  sizeof *pg_ls->ports);
+    if (ls_pg_rec) {
+        hmap_remove(nb_pgs, &ls_pg_rec->key_node);
+        sset_destroy(&ls_pg_rec->ports);
+        free(ls_pg_rec);
     }
-    pg_ls->ports[pg_ls->n_ports++] = op;
 }
 
-struct ovn_ls_port_group {
-    struct hmap_node key_node;  /* Index on 'key'. */
-    struct uuid key;            /* nb_pg->header_.uuid. */
-    const struct nbrec_port_group *nb_pg;
-};
 
-static void
-ovn_ls_port_group_add(struct hmap *nb_pgs,
-                      const struct nbrec_port_group *nb_pg)
+static struct ls_port_group *
+ls_port_group_create(struct hmap *ls_port_groups,
+                     const struct nbrec_logical_switch *nbs,
+                     const struct sbrec_datapath_binding *dp)
 {
-    struct ovn_ls_port_group *ls_pg = xzalloc(sizeof *ls_pg);
-    ls_pg->key = nb_pg->header_.uuid;
-    ls_pg->nb_pg = nb_pg;
-    hmap_insert(nb_pgs, &ls_pg->key_node, uuid_hash(&ls_pg->key));
+    struct ls_port_group *ls_pg = xmalloc(sizeof *ls_pg);
+
+    *ls_pg = (struct ls_port_group) {
+        .nbs = nbs,
+        .sb_datapath_key = dp->tunnel_key,
+        .nb_pgs = HMAP_INITIALIZER(&ls_pg->nb_pgs),
+    };
+    hmap_insert(ls_port_groups, &ls_pg->key_node,
+                uuid_hash(&nbs->header_.uuid));
+    return ls_pg;
 }
 
 static void
-ovn_ls_port_group_destroy(struct hmap *nb_pgs)
+ls_port_group_destroy(struct hmap *ls_port_groups, struct ls_port_group *ls_pg)
 {
-    struct ovn_ls_port_group *ls_pg;
-    HMAP_FOR_EACH_POP (ls_pg, key_node, nb_pgs) {
+    if (ls_pg) {
+        struct ls_port_group_record *ls_pg_rec;
+        HMAP_FOR_EACH_SAFE (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
+            ls_port_group_record_destroy(&ls_pg->nb_pgs, ls_pg_rec);
+        }
+        hmap_destroy(&ls_pg->nb_pgs);
+        hmap_remove(ls_port_groups, &ls_pg->key_node);
         free(ls_pg);
     }
-    hmap_destroy(nb_pgs);
+}
+
+static struct ls_port_group *
+ls_port_group_find(const struct hmap *ls_port_groups,
+                   const struct nbrec_logical_switch *nbs)
+{
+    struct ls_port_group *ls_pg;
+
+    HMAP_FOR_EACH_WITH_HASH (ls_pg, key_node, uuid_hash(&nbs->header_.uuid),
+                             ls_port_groups) {
+        if (nbs == ls_pg->nbs) {
+            return ls_pg;
+        }
+    }
+    return NULL;
 }
 
 static bool
@@ -6350,7 +6351,7 @@ od_set_acl_flags(struct ovn_datapath *od, struct 
nbrec_acl **acls,
 }
 
 static void
-ls_get_acl_flags(struct ovn_datapath *od)
+ls_get_acl_flags(struct ovn_datapath *od, const struct hmap *ls_port_groups)
 {
     od->has_acls = false;
     od->has_stateful_acl = false;
@@ -6360,9 +6361,18 @@ ls_get_acl_flags(struct ovn_datapath *od)
         return;
     }
 
-    struct ovn_ls_port_group *ls_pg;
-    HMAP_FOR_EACH (ls_pg, key_node, &od->nb_pgs) {
-        if (od_set_acl_flags(od, ls_pg->nb_pg->acls, ls_pg->nb_pg->n_acls)) {
+    const struct ls_port_group *ls_pg;
+
+    ls_pg = ls_port_group_find(ls_port_groups, od->nbs);
+    if (!ls_pg) {
+        return;
+    }
+
+
+    struct ls_port_group_record *ls_pg_rec;
+    HMAP_FOR_EACH (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
+        if (od_set_acl_flags(od, ls_pg_rec->nb_pg->acls,
+                             ls_pg_rec->nb_pg->n_acls)) {
             return;
         }
     }
@@ -6568,7 +6578,7 @@ build_stateless_filter(struct ovn_datapath *od,
 
 static void
 build_stateless_filters(struct ovn_datapath *od,
-                        const struct hmap *port_groups,
+                        const struct hmap *ls_port_groups,
                         struct hmap *lflows)
 {
     for (size_t i = 0; i < od->nbs->n_acls; i++) {
@@ -6578,21 +6588,26 @@ build_stateless_filters(struct ovn_datapath *od,
         }
     }
 
-    struct ovn_port_group *pg;
-    HMAP_FOR_EACH (pg, key_node, port_groups) {
-        if (ovn_port_group_ls_find(pg, &od->nbs->header_.uuid)) {
-            for (size_t i = 0; i < pg->nb_pg->n_acls; i++) {
-                const struct nbrec_acl *acl = pg->nb_pg->acls[i];
-                if (!strcmp(acl->action, "allow-stateless")) {
-                    build_stateless_filter(od, acl, lflows);
-                }
+    const struct ls_port_group *ls_pg = ls_port_group_find(ls_port_groups,
+                                                           od->nbs);
+    if (!ls_pg) {
+        return;
+    }
+
+    const struct ls_port_group_record *ls_pg_rec;
+    HMAP_FOR_EACH (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
+        for (size_t i = 0; i < ls_pg_rec->nb_pg->n_acls; i++) {
+            const struct nbrec_acl *acl = ls_pg_rec->nb_pg->acls[i];
+
+            if (!strcmp(acl->action, "allow-stateless")) {
+                build_stateless_filter(od, acl, lflows);
             }
         }
     }
 }
 
 static void
-build_pre_acls(struct ovn_datapath *od, const struct hmap *port_groups,
+build_pre_acls(struct ovn_datapath *od, const struct hmap *ls_port_groups,
                struct hmap *lflows)
 {
     /* Ingress and Egress Pre-ACL Table (Priority 0): Packets are
@@ -6623,7 +6638,7 @@ build_pre_acls(struct ovn_datapath *od, const struct hmap 
*port_groups,
         }
 
         /* stateless filters always take precedence over stateful ACLs. */
-        build_stateless_filters(od, port_groups, lflows);
+        build_stateless_filters(od, ls_port_groups, lflows);
 
         /* Ingress and Egress Pre-ACL Table (Priority 110).
          *
@@ -6657,7 +6672,7 @@ build_pre_acls(struct ovn_datapath *od, const struct hmap 
*port_groups,
     } else if (od->has_lb_vip) {
         /* We'll build stateless filters if there are LB rules so that
          * the stateless flows are not tracked in pre-lb. */
-         build_stateless_filters(od, port_groups, lflows);
+         build_stateless_filters(od, ls_port_groups, lflows);
     }
 }
 
@@ -7218,33 +7233,6 @@ consider_acl(struct hmap *lflows, struct ovn_datapath 
*od,
     }
 }
 
-static struct ovn_port_group *
-ovn_port_group_create(struct hmap *pgs,
-                      const struct nbrec_port_group *nb_pg)
-{
-    struct ovn_port_group *pg = xzalloc(sizeof *pg);
-    pg->key = nb_pg->header_.uuid;
-    pg->nb_pg = nb_pg;
-    hmap_init(&pg->nb_lswitches);
-    hmap_insert(pgs, &pg->key_node, uuid_hash(&pg->key));
-    return pg;
-}
-
-static void
-ovn_port_group_destroy(struct hmap *pgs, struct ovn_port_group *pg)
-{
-    if (pg) {
-        hmap_remove(pgs, &pg->key_node);
-        struct ovn_port_group_ls *ls;
-        HMAP_FOR_EACH_POP (ls, key_node, &pg->nb_lswitches) {
-            free(ls->ports);
-            free(ls);
-        }
-        hmap_destroy(&pg->nb_lswitches);
-        free(pg);
-    }
-}
-
 static void
 copy_ra_to_sb(struct ovn_port *op, const char *address_mode);
 
@@ -7316,13 +7304,12 @@ ovn_update_ipv6_options(struct hmap *lr_ports)
 static void
 build_port_group_lswitches(
     const struct nbrec_port_group_table *nbrec_port_group_table,
-    struct hmap *pgs, struct hmap *ls_ports)
+    struct hmap *ls_pgs, struct hmap *ls_ports)
 {
-    hmap_init(pgs);
+    hmap_init(ls_pgs);
 
     const struct nbrec_port_group *nb_pg;
     NBREC_PORT_GROUP_TABLE_FOR_EACH (nb_pg, nbrec_port_group_table) {
-        struct ovn_port_group *pg = ovn_port_group_create(pgs, nb_pg);
         for (size_t i = 0; i < nb_pg->n_ports; i++) {
             struct ovn_port *op = ovn_port_find(ls_ports,
                                                 nb_pg->ports[i]->name);
@@ -7342,13 +7329,12 @@ build_port_group_lswitches(
                 continue;
             }
 
-            struct ovn_port_group_ls *pg_ls =
-                ovn_port_group_ls_find(pg, &op->od->nbs->header_.uuid);
-            if (!pg_ls) {
-                pg_ls = ovn_port_group_ls_add(pg, op->od);
-                ovn_ls_port_group_add(&op->od->nb_pgs, nb_pg);
+            struct ls_port_group *ls_pg =
+                ls_port_group_find(ls_pgs, op->od->nbs);
+            if (!ls_pg) {
+                ls_pg = ls_port_group_create(ls_pgs, op->od->nbs, op->od->sb);
             }
-            ovn_port_group_ls_add_port(pg_ls, op);
+            ls_port_group_record_add(&ls_pg->nb_pgs, nb_pg, op->key);
         }
     }
 }
@@ -7505,7 +7491,7 @@ build_acl_log_related_flows(struct ovn_datapath *od, 
struct hmap *lflows,
 
 static void
 build_acls(struct ovn_datapath *od, const struct chassis_features *features,
-           struct hmap *lflows, const struct hmap *port_groups,
+           struct hmap *lflows, const struct hmap *ls_port_groups,
            const struct shash *meter_groups)
 {
     const char *default_acl_action = default_acl_drop
@@ -7691,11 +7677,15 @@ build_acls(struct ovn_datapath *od, const struct 
chassis_features *features,
                      features->ct_no_masked_label,
                      meter_groups, &match, &actions);
     }
-    struct ovn_port_group *pg;
-    HMAP_FOR_EACH (pg, key_node, port_groups) {
-        if (ovn_port_group_ls_find(pg, &od->nbs->header_.uuid)) {
-            for (size_t i = 0; i < pg->nb_pg->n_acls; i++) {
-                const struct nbrec_acl *acl = pg->nb_pg->acls[i];
+
+    const struct ls_port_group *ls_pg = ls_port_group_find(ls_port_groups,
+                                                           od->nbs);
+    if (ls_pg) {
+        const struct ls_port_group_record *ls_pg_rec;
+        HMAP_FOR_EACH (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
+            for (size_t i = 0; i < ls_pg_rec->nb_pg->n_acls; i++) {
+                const struct nbrec_acl *acl = ls_pg_rec->nb_pg->acls[i];
+
                 build_acl_log_related_flows(od, lflows, acl, has_stateful,
                                             features->ct_no_masked_label,
                                             meter_groups, &match, &actions);
@@ -9199,19 +9189,19 @@ build_lswitch_lflows_l2_unknown(struct ovn_datapath *od,
  * Ingress tables 3 through 10.  Egress tables 0 through 7. */
 static void
 build_lswitch_lflows_pre_acl_and_acl(struct ovn_datapath *od,
-                                     const struct hmap *port_groups,
+                                     const struct hmap *ls_port_groups,
                                      const struct chassis_features *features,
                                      struct hmap *lflows,
                                      const struct shash *meter_groups)
 {
     ovs_assert(od->nbs);
-    ls_get_acl_flags(od);
+    ls_get_acl_flags(od, ls_port_groups);
 
-    build_pre_acls(od, port_groups, lflows);
+    build_pre_acls(od, ls_port_groups, lflows);
     build_pre_lb(od, meter_groups, lflows);
     build_pre_stateful(od, features, lflows);
     build_acl_hints(od, features, lflows);
-    build_acls(od, features, lflows, port_groups, meter_groups);
+    build_acls(od, features, lflows, ls_port_groups, meter_groups);
     build_qos(od, lflows);
     build_stateful(od, features, lflows);
     build_lb_hairpin(od, lflows);
@@ -15512,7 +15502,7 @@ struct lswitch_flow_build_info {
     const struct ovn_datapaths *lr_datapaths;
     const struct hmap *ls_ports;
     const struct hmap *lr_ports;
-    const struct hmap *port_groups;
+    const struct hmap *ls_port_groups;
     struct hmap *lflows;
     struct hmap *igmp_groups;
     const struct shash *meter_groups;
@@ -15536,7 +15526,7 @@ build_lswitch_and_lrouter_iterate_by_ls(struct 
ovn_datapath *od,
                                         struct lswitch_flow_build_info *lsi)
 {
     ovs_assert(od->nbs);
-    build_lswitch_lflows_pre_acl_and_acl(od, lsi->port_groups,
+    build_lswitch_lflows_pre_acl_and_acl(od, lsi->ls_port_groups,
                                          lsi->features,
                                          lsi->lflows,
                                          lsi->meter_groups);
@@ -15810,7 +15800,7 @@ build_lswitch_and_lrouter_flows(const struct 
ovn_datapaths *ls_datapaths,
                                 const struct ovn_datapaths *lr_datapaths,
                                 const struct hmap *ls_ports,
                                 const struct hmap *lr_ports,
-                                const struct hmap *port_groups,
+                                const struct hmap *ls_port_groups,
                                 struct hmap *lflows,
                                 struct hmap *igmp_groups,
                                 const struct shash *meter_groups,
@@ -15838,7 +15828,7 @@ build_lswitch_and_lrouter_flows(const struct 
ovn_datapaths *ls_datapaths,
             lsiv[index].lr_datapaths = lr_datapaths;
             lsiv[index].ls_ports = ls_ports;
             lsiv[index].lr_ports = lr_ports;
-            lsiv[index].port_groups = port_groups;
+            lsiv[index].ls_port_groups = ls_port_groups;
             lsiv[index].igmp_groups = igmp_groups;
             lsiv[index].meter_groups = meter_groups;
             lsiv[index].lbs = lbs;
@@ -15871,7 +15861,7 @@ build_lswitch_and_lrouter_flows(const struct 
ovn_datapaths *ls_datapaths,
             .lr_datapaths = lr_datapaths,
             .ls_ports = ls_ports,
             .lr_ports = lr_ports,
-            .port_groups = port_groups,
+            .ls_port_groups = ls_port_groups,
             .lflows = lflows,
             .igmp_groups = igmp_groups,
             .meter_groups = meter_groups,
@@ -16015,7 +16005,8 @@ void build_lflows(struct ovsdb_idl_txn *ovnsb_txn,
                                     input_data->lr_datapaths,
                                     input_data->ls_ports,
                                     input_data->lr_ports,
-                                    input_data->port_groups, lflows,
+                                    input_data->ls_port_groups,
+                                    lflows,
                                     &igmp_groups,
                                     input_data->meter_groups, input_data->lbs,
                                     input_data->bfd_connections,
@@ -16562,7 +16553,7 @@ bool lflow_handle_northd_ls_changes(struct 
ovsdb_idl_txn *ovnsb_txn,
 static void
 sync_port_groups(struct ovsdb_idl_txn *ovnsb_txn,
                  const struct sbrec_port_group_table *sbrec_port_group_table,
-                 struct hmap *pgs)
+                 struct hmap *ls_pgs)
 {
     struct shash sb_port_groups = SHASH_INITIALIZER(&sb_port_groups);
 
@@ -16573,12 +16564,13 @@ sync_port_groups(struct ovsdb_idl_txn *ovnsb_txn,
 
     struct ds sb_name = DS_EMPTY_INITIALIZER;
 
-    struct ovn_port_group *pg;
-    HMAP_FOR_EACH (pg, key_node, pgs) {
+    struct ls_port_group *ls_pg;
+    HMAP_FOR_EACH (ls_pg, key_node, ls_pgs) {
+        struct ls_port_group_record *ls_pg_rec;
 
-        struct ovn_port_group_ls *pg_ls;
-        HMAP_FOR_EACH (pg_ls, key_node, &pg->nb_lswitches) {
-            get_sb_port_group_name(pg->nb_pg->name, pg_ls->od->sb->tunnel_key,
+        HMAP_FOR_EACH (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
+            get_sb_port_group_name(ls_pg_rec->nb_pg->name,
+                                   ls_pg->sb_datapath_key,
                                    &sb_name);
             sb_port_group = shash_find_and_delete(&sb_port_groups,
                                                   ds_cstr(&sb_name));
@@ -16587,14 +16579,10 @@ sync_port_groups(struct ovsdb_idl_txn *ovnsb_txn,
                 sbrec_port_group_set_name(sb_port_group, ds_cstr(&sb_name));
             }
 
-            const char **nb_port_names = xcalloc(pg_ls->n_ports,
-                                                 sizeof *nb_port_names);
-            for (size_t i = 0; i < pg_ls->n_ports; i++) {
-                nb_port_names[i] = pg_ls->ports[i]->nbsp->name;
-            }
+            const char **nb_port_names = sset_array(&ls_pg_rec->ports);
             sbrec_port_group_set_ports(sb_port_group,
                                        nb_port_names,
-                                       pg_ls->n_ports);
+                                       sset_count(&ls_pg_rec->ports));
             free(nb_port_names);
         }
     }
@@ -17418,7 +17406,7 @@ northd_init(struct northd_data *data)
     ovn_datapaths_init(&data->lr_datapaths);
     hmap_init(&data->ls_ports);
     hmap_init(&data->lr_ports);
-    hmap_init(&data->port_groups);
+    hmap_init(&data->ls_port_groups);
     shash_init(&data->meter_groups);
     hmap_init(&data->lbs);
     hmap_init(&data->lb_groups);
@@ -17450,12 +17438,11 @@ northd_destroy(struct northd_data *data)
     }
     hmap_destroy(&data->lb_groups);
 
-    struct ovn_port_group *pg;
-    HMAP_FOR_EACH_SAFE (pg, key_node, &data->port_groups) {
-        ovn_port_group_destroy(&data->port_groups, pg);
+    struct ls_port_group *ls_pg;
+    HMAP_FOR_EACH_SAFE (ls_pg, key_node, &data->ls_port_groups) {
+        ls_port_group_destroy(&data->ls_port_groups, ls_pg);
     }
-
-    hmap_destroy(&data->port_groups);
+    hmap_destroy(&data->ls_port_groups);
 
     struct shash_node *node;
     SHASH_FOR_EACH_SAFE (node, &data->meter_groups) {
@@ -17596,7 +17583,8 @@ ovnnb_db_run(struct northd_input *input_data,
                        ods_size(&data->lr_datapaths));
     build_ipam(&data->ls_datapaths.datapaths, &data->ls_ports);
     build_port_group_lswitches(input_data->nbrec_port_group_table,
-                               &data->port_groups, &data->ls_ports);
+                               &data->ls_port_groups,
+                               &data->ls_ports);
     build_lrouter_groups(&data->lr_ports, &data->lr_list);
     build_ip_mcast(ovnsb_txn, input_data->sbrec_ip_multicast_table,
                    input_data->sbrec_ip_mcast_by_dp,
@@ -17615,7 +17603,7 @@ ovnnb_db_run(struct northd_input *input_data,
     sync_lbs(ovnsb_txn, input_data->sbrec_load_balancer_table,
              &data->ls_datapaths, &data->lbs);
     sync_port_groups(ovnsb_txn, input_data->sbrec_port_group_table,
-                     &data->port_groups);
+                     &data->ls_port_groups);
     sync_meters(ovnsb_txn, input_data->nbrec_meter_table,
                 input_data->nbrec_acl_table, input_data->sbrec_meter_table,
                 &data->meter_groups);
diff --git a/northd/northd.h b/northd/northd.h
index f3e63b1e1a..38bc7f50f1 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -108,7 +108,7 @@ struct northd_data {
     struct ovn_datapaths lr_datapaths;
     struct hmap ls_ports;
     struct hmap lr_ports;
-    struct hmap port_groups;
+    struct hmap ls_port_groups;         /* Stores struct ls_port_group. */
     struct shash meter_groups;
     struct hmap lbs;
     struct hmap lb_groups;
@@ -144,7 +144,7 @@ struct lflow_input {
     const struct ovn_datapaths *lr_datapaths;
     const struct hmap *ls_ports;
     const struct hmap *lr_ports;
-    const struct hmap *port_groups;
+    const struct hmap *ls_port_groups;
     const struct shash *meter_groups;
     const struct hmap *lbs;
     const struct hmap *bfd_connections;
@@ -309,14 +309,29 @@ struct ovn_datapath {
      * Valid only if it is logical router datapath. NULL otherwise. */
     struct lrouter_group *lr_group;
 
-    /* Port groups related to the datapath, used only when nbs is NOT NULL. */
-    struct hmap nb_pgs;
-
     /* Map of ovn_port objects belonging to this datapath.
      * This map doesn't include derived ports. */
     struct hmap ports;
 };
 
+/* Per logical switch port group information. */
+struct ls_port_group {
+    struct hmap_node key_node;  /* Index on 'nbs->header_.uuid'. */
+
+    const struct nbrec_logical_switch *nbs;
+    int64_t sb_datapath_key; /* SB.Datapath_Binding.tunnel_key. */
+
+    /* Port groups with ports attached to 'nbs'. */
+    struct hmap nb_pgs; /* Stores struct ls_port_group_record. */
+};
+
+struct ls_port_group_record {
+    struct hmap_node key_node;  /* Index on 'nb_pg->header_.uuid'. */
+
+    const struct nbrec_port_group *nb_pg;
+    struct sset ports;          /* Subset of 'nb_pg' ports in this record. */
+};
+
 void ovnnb_db_run(struct northd_input *input_data,
                   struct northd_data *data,
                   struct ovsdb_idl_txn *ovnnb_txn,

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to