Re: [ovs-dev] [PATCH ovn v2 2/2] northd: Add I-P for syncing SB address sets.

2022-11-15 Thread Numan Siddique
On Tue, Nov 15, 2022 at 11:10 AM Mark Michelson  wrote:
>
> On 11/14/22 16:34, Numan Siddique wrote:
> > On Mon, Nov 14, 2022 at 3:23 PM Mark Michelson  wrote:
> >>
> >> Hi Numan, I have just one minor suggestion below.
> >>
> >> On 11/14/22 11:48, num...@ovn.org wrote:
> >>> From: Numan Siddique 
> >>>
> >>> Updates to NB address sets and NB port groups are handled
> >>> incrementally for syncing the SB address sets.  This patch
> >>> doesn't support syncing the SB Address sets for the router
> >>> load balancer vips incrementally, instead a full recompute is
> >>> triggered for any changes to NB load balancers, NB load balancer
> >>> groups and NB logical routers.
> >>>
> >>> Signed-off-by: Numan Siddique 
> >>> ---
> >>>northd/en-sb-sync.c  | 202 ---
> >>>northd/en-sb-sync.h  |   6 ++
> >>>northd/inc-proc-northd.c |  18 +++-
> >>>tests/ovn-northd.at  |  52 ++
> >>>4 files changed, 260 insertions(+), 18 deletions(-)
> >>>
> >>> diff --git a/northd/en-sb-sync.c b/northd/en-sb-sync.c
> >>> index c3ba315df..8a17998ec 100644
> >>> --- a/northd/en-sb-sync.c
> >>> +++ b/northd/en-sb-sync.c
> >>> @@ -22,6 +22,7 @@
> >>>#include "openvswitch/util.h"
> >>>
> >>>#include "en-sb-sync.h"
> >>> +#include "include/ovn/expr.h"
> >>>#include "lib/inc-proc-eng.h"
> >>>#include "lib/lb.h"
> >>>#include "lib/ovn-nb-idl.h"
> >>> @@ -41,6 +42,13 @@ static void sync_address_sets(const struct 
> >>> nbrec_address_set_table *,
> >>>  const struct sbrec_address_set_table *,
> >>>  struct ovsdb_idl_txn *ovnsb_txn,
> >>>  struct hmap *datapaths);
> >>> +static const struct sbrec_address_set *sb_address_set_lookup_by_name(
> >>> +struct ovsdb_idl_index *, const char *name);
> >>> +static void update_sb_addr_set(const char **nb_addresses, size_t 
> >>> n_addresses,
> >>> +   const struct sbrec_address_set *);
> >>> +static void build_port_group_address_set(const struct nbrec_port_group *,
> >>> + struct svec *ipv4_addrs,
> >>> + struct svec *ipv6_addrs);
> >>>
> >>>void *
> >>>en_sb_sync_init(struct engine_node *node OVS_UNUSED,
> >>> @@ -94,6 +102,98 @@ en_address_set_sync_cleanup(void *data OVS_UNUSED)
> >>>
> >>>}
> >>>
> >>> +bool
> >>> +address_set_sync_nb_address_set_handler(struct engine_node *node 
> >>> OVS_UNUSED,
> >>> +void *data OVS_UNUSED)
> >>> +{
> >>> +const struct nbrec_address_set_table *nb_address_set_table =
> >>> +EN_OVSDB_GET(engine_get_input("NB_address_set", node));
> >>> +
> >>> +/* Return false if an address set is created or deleted.
> >>> + * Handle I-P for only updated address sets. */
> >>> +const struct nbrec_address_set *nb_addr_set;
> >>> +NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
> >>> +  nb_address_set_table) {
> >>> +if (nbrec_address_set_is_new(nb_addr_set) ||
> >>> +nbrec_address_set_is_deleted(nb_addr_set)) {
> >>> +return false;
> >>> +}
> >>> +}
> >>> +
> >>> +struct ovsdb_idl_index *sbrec_address_set_by_name =
> >>> +engine_ovsdb_node_get_index(
> >>> +engine_get_input("SB_address_set", node),
> >>> +"sbrec_address_set_by_name");
> >>> +
> >>> +NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
> >>> +  nb_address_set_table) {
> >>> +const struct sbrec_address_set *sb_addr_set =
> >>> +sb_address_set_lookup_by_name(sbrec_address_set_by_name,
> >>> +  nb_addr_set->name);
> >>> +if (!sb_addr_set) {
> >>> +return false;
> >>> +}
> >>> +update_sb_addr_set((const char **) nb_addr_set->addresses,
> >>> +   nb_addr_set->n_addresses, sb_addr_set);
> >>> +}
> >>> +
> >>> +return true;
> >>> +}
> >>> +
> >>> +bool
> >>> +address_set_sync_nb_port_group_handler(struct engine_node *node 
> >>> OVS_UNUSED,
> >>> +   void *data OVS_UNUSED)
> >>> +{
> >>> +const struct nbrec_port_group *nb_pg;
> >>> +const struct nbrec_port_group_table *nb_port_group_table =
> >>> +EN_OVSDB_GET(engine_get_input("NB_port_group", node));
> >>> +NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) 
> >>> {
> >>> +if (nbrec_port_group_is_new(nb_pg) ||
> >>> +nbrec_port_group_is_deleted(nb_pg)) {
> >>> +return false;
> >>> +}
> >>> +}
> >>> +
> >>> +struct ovsdb_idl_index *sbrec_address_set_by_name =
> >>> +engine_ovsdb_node_get_index(
> >>> +engine_get_input("SB_address_set", 

Re: [ovs-dev] [PATCH ovn v2 2/2] northd: Add I-P for syncing SB address sets.

2022-11-15 Thread Mark Michelson

On 11/14/22 16:34, Numan Siddique wrote:

On Mon, Nov 14, 2022 at 3:23 PM Mark Michelson  wrote:


Hi Numan, I have just one minor suggestion below.

On 11/14/22 11:48, num...@ovn.org wrote:

From: Numan Siddique 

Updates to NB address sets and NB port groups are handled
incrementally for syncing the SB address sets.  This patch
doesn't support syncing the SB Address sets for the router
load balancer vips incrementally, instead a full recompute is
triggered for any changes to NB load balancers, NB load balancer
groups and NB logical routers.

Signed-off-by: Numan Siddique 
---
   northd/en-sb-sync.c  | 202 ---
   northd/en-sb-sync.h  |   6 ++
   northd/inc-proc-northd.c |  18 +++-
   tests/ovn-northd.at  |  52 ++
   4 files changed, 260 insertions(+), 18 deletions(-)

diff --git a/northd/en-sb-sync.c b/northd/en-sb-sync.c
index c3ba315df..8a17998ec 100644
--- a/northd/en-sb-sync.c
+++ b/northd/en-sb-sync.c
@@ -22,6 +22,7 @@
   #include "openvswitch/util.h"

   #include "en-sb-sync.h"
+#include "include/ovn/expr.h"
   #include "lib/inc-proc-eng.h"
   #include "lib/lb.h"
   #include "lib/ovn-nb-idl.h"
@@ -41,6 +42,13 @@ static void sync_address_sets(const struct 
nbrec_address_set_table *,
 const struct sbrec_address_set_table *,
 struct ovsdb_idl_txn *ovnsb_txn,
 struct hmap *datapaths);
+static const struct sbrec_address_set *sb_address_set_lookup_by_name(
+struct ovsdb_idl_index *, const char *name);
+static void update_sb_addr_set(const char **nb_addresses, size_t n_addresses,
+   const struct sbrec_address_set *);
+static void build_port_group_address_set(const struct nbrec_port_group *,
+ struct svec *ipv4_addrs,
+ struct svec *ipv6_addrs);

   void *
   en_sb_sync_init(struct engine_node *node OVS_UNUSED,
@@ -94,6 +102,98 @@ en_address_set_sync_cleanup(void *data OVS_UNUSED)

   }

+bool
+address_set_sync_nb_address_set_handler(struct engine_node *node OVS_UNUSED,
+void *data OVS_UNUSED)
+{
+const struct nbrec_address_set_table *nb_address_set_table =
+EN_OVSDB_GET(engine_get_input("NB_address_set", node));
+
+/* Return false if an address set is created or deleted.
+ * Handle I-P for only updated address sets. */
+const struct nbrec_address_set *nb_addr_set;
+NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
+  nb_address_set_table) {
+if (nbrec_address_set_is_new(nb_addr_set) ||
+nbrec_address_set_is_deleted(nb_addr_set)) {
+return false;
+}
+}
+
+struct ovsdb_idl_index *sbrec_address_set_by_name =
+engine_ovsdb_node_get_index(
+engine_get_input("SB_address_set", node),
+"sbrec_address_set_by_name");
+
+NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
+  nb_address_set_table) {
+const struct sbrec_address_set *sb_addr_set =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  nb_addr_set->name);
+if (!sb_addr_set) {
+return false;
+}
+update_sb_addr_set((const char **) nb_addr_set->addresses,
+   nb_addr_set->n_addresses, sb_addr_set);
+}
+
+return true;
+}
+
+bool
+address_set_sync_nb_port_group_handler(struct engine_node *node OVS_UNUSED,
+   void *data OVS_UNUSED)
+{
+const struct nbrec_port_group *nb_pg;
+const struct nbrec_port_group_table *nb_port_group_table =
+EN_OVSDB_GET(engine_get_input("NB_port_group", node));
+NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
+if (nbrec_port_group_is_new(nb_pg) ||
+nbrec_port_group_is_deleted(nb_pg)) {
+return false;
+}
+}
+
+struct ovsdb_idl_index *sbrec_address_set_by_name =
+engine_ovsdb_node_get_index(
+engine_get_input("SB_address_set", node),
+"sbrec_address_set_by_name");
+NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
+char *ipv4_addrs_name = xasprintf("%s_ip4", nb_pg->name);
+const struct sbrec_address_set *sb_addr_set_v4 =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  ipv4_addrs_name);
+if (!sb_addr_set_v4) {
+free(ipv4_addrs_name);
+return false;
+}
+char *ipv6_addrs_name = xasprintf("%s_ip6", nb_pg->name);
+const struct sbrec_address_set *sb_addr_set_v6 =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+   

Re: [ovs-dev] [PATCH ovn v2 2/2] northd: Add I-P for syncing SB address sets.

2022-11-14 Thread Numan Siddique
On Mon, Nov 14, 2022 at 3:23 PM Mark Michelson  wrote:
>
> Hi Numan, I have just one minor suggestion below.
>
> On 11/14/22 11:48, num...@ovn.org wrote:
> > From: Numan Siddique 
> >
> > Updates to NB address sets and NB port groups are handled
> > incrementally for syncing the SB address sets.  This patch
> > doesn't support syncing the SB Address sets for the router
> > load balancer vips incrementally, instead a full recompute is
> > triggered for any changes to NB load balancers, NB load balancer
> > groups and NB logical routers.
> >
> > Signed-off-by: Numan Siddique 
> > ---
> >   northd/en-sb-sync.c  | 202 ---
> >   northd/en-sb-sync.h  |   6 ++
> >   northd/inc-proc-northd.c |  18 +++-
> >   tests/ovn-northd.at  |  52 ++
> >   4 files changed, 260 insertions(+), 18 deletions(-)
> >
> > diff --git a/northd/en-sb-sync.c b/northd/en-sb-sync.c
> > index c3ba315df..8a17998ec 100644
> > --- a/northd/en-sb-sync.c
> > +++ b/northd/en-sb-sync.c
> > @@ -22,6 +22,7 @@
> >   #include "openvswitch/util.h"
> >
> >   #include "en-sb-sync.h"
> > +#include "include/ovn/expr.h"
> >   #include "lib/inc-proc-eng.h"
> >   #include "lib/lb.h"
> >   #include "lib/ovn-nb-idl.h"
> > @@ -41,6 +42,13 @@ static void sync_address_sets(const struct 
> > nbrec_address_set_table *,
> > const struct sbrec_address_set_table *,
> > struct ovsdb_idl_txn *ovnsb_txn,
> > struct hmap *datapaths);
> > +static const struct sbrec_address_set *sb_address_set_lookup_by_name(
> > +struct ovsdb_idl_index *, const char *name);
> > +static void update_sb_addr_set(const char **nb_addresses, size_t 
> > n_addresses,
> > +   const struct sbrec_address_set *);
> > +static void build_port_group_address_set(const struct nbrec_port_group *,
> > + struct svec *ipv4_addrs,
> > + struct svec *ipv6_addrs);
> >
> >   void *
> >   en_sb_sync_init(struct engine_node *node OVS_UNUSED,
> > @@ -94,6 +102,98 @@ en_address_set_sync_cleanup(void *data OVS_UNUSED)
> >
> >   }
> >
> > +bool
> > +address_set_sync_nb_address_set_handler(struct engine_node *node 
> > OVS_UNUSED,
> > +void *data OVS_UNUSED)
> > +{
> > +const struct nbrec_address_set_table *nb_address_set_table =
> > +EN_OVSDB_GET(engine_get_input("NB_address_set", node));
> > +
> > +/* Return false if an address set is created or deleted.
> > + * Handle I-P for only updated address sets. */
> > +const struct nbrec_address_set *nb_addr_set;
> > +NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
> > +  nb_address_set_table) {
> > +if (nbrec_address_set_is_new(nb_addr_set) ||
> > +nbrec_address_set_is_deleted(nb_addr_set)) {
> > +return false;
> > +}
> > +}
> > +
> > +struct ovsdb_idl_index *sbrec_address_set_by_name =
> > +engine_ovsdb_node_get_index(
> > +engine_get_input("SB_address_set", node),
> > +"sbrec_address_set_by_name");
> > +
> > +NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
> > +  nb_address_set_table) {
> > +const struct sbrec_address_set *sb_addr_set =
> > +sb_address_set_lookup_by_name(sbrec_address_set_by_name,
> > +  nb_addr_set->name);
> > +if (!sb_addr_set) {
> > +return false;
> > +}
> > +update_sb_addr_set((const char **) nb_addr_set->addresses,
> > +   nb_addr_set->n_addresses, sb_addr_set);
> > +}
> > +
> > +return true;
> > +}
> > +
> > +bool
> > +address_set_sync_nb_port_group_handler(struct engine_node *node OVS_UNUSED,
> > +   void *data OVS_UNUSED)
> > +{
> > +const struct nbrec_port_group *nb_pg;
> > +const struct nbrec_port_group_table *nb_port_group_table =
> > +EN_OVSDB_GET(engine_get_input("NB_port_group", node));
> > +NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
> > +if (nbrec_port_group_is_new(nb_pg) ||
> > +nbrec_port_group_is_deleted(nb_pg)) {
> > +return false;
> > +}
> > +}
> > +
> > +struct ovsdb_idl_index *sbrec_address_set_by_name =
> > +engine_ovsdb_node_get_index(
> > +engine_get_input("SB_address_set", node),
> > +"sbrec_address_set_by_name");
> > +NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
> > +char *ipv4_addrs_name = xasprintf("%s_ip4", nb_pg->name);
> > +const struct sbrec_address_set *sb_addr_set_v4 =
> > +sb_address_set_lookup_by_name(sbrec_address_set_by_name,
> > + 

Re: [ovs-dev] [PATCH ovn v2 2/2] northd: Add I-P for syncing SB address sets.

2022-11-14 Thread Mark Michelson

Hi Numan, I have just one minor suggestion below.

On 11/14/22 11:48, num...@ovn.org wrote:

From: Numan Siddique 

Updates to NB address sets and NB port groups are handled
incrementally for syncing the SB address sets.  This patch
doesn't support syncing the SB Address sets for the router
load balancer vips incrementally, instead a full recompute is
triggered for any changes to NB load balancers, NB load balancer
groups and NB logical routers.

Signed-off-by: Numan Siddique 
---
  northd/en-sb-sync.c  | 202 ---
  northd/en-sb-sync.h  |   6 ++
  northd/inc-proc-northd.c |  18 +++-
  tests/ovn-northd.at  |  52 ++
  4 files changed, 260 insertions(+), 18 deletions(-)

diff --git a/northd/en-sb-sync.c b/northd/en-sb-sync.c
index c3ba315df..8a17998ec 100644
--- a/northd/en-sb-sync.c
+++ b/northd/en-sb-sync.c
@@ -22,6 +22,7 @@
  #include "openvswitch/util.h"
  
  #include "en-sb-sync.h"

+#include "include/ovn/expr.h"
  #include "lib/inc-proc-eng.h"
  #include "lib/lb.h"
  #include "lib/ovn-nb-idl.h"
@@ -41,6 +42,13 @@ static void sync_address_sets(const struct 
nbrec_address_set_table *,
const struct sbrec_address_set_table *,
struct ovsdb_idl_txn *ovnsb_txn,
struct hmap *datapaths);
+static const struct sbrec_address_set *sb_address_set_lookup_by_name(
+struct ovsdb_idl_index *, const char *name);
+static void update_sb_addr_set(const char **nb_addresses, size_t n_addresses,
+   const struct sbrec_address_set *);
+static void build_port_group_address_set(const struct nbrec_port_group *,
+ struct svec *ipv4_addrs,
+ struct svec *ipv6_addrs);
  
  void *

  en_sb_sync_init(struct engine_node *node OVS_UNUSED,
@@ -94,6 +102,98 @@ en_address_set_sync_cleanup(void *data OVS_UNUSED)
  
  }
  
+bool

+address_set_sync_nb_address_set_handler(struct engine_node *node OVS_UNUSED,
+void *data OVS_UNUSED)
+{
+const struct nbrec_address_set_table *nb_address_set_table =
+EN_OVSDB_GET(engine_get_input("NB_address_set", node));
+
+/* Return false if an address set is created or deleted.
+ * Handle I-P for only updated address sets. */
+const struct nbrec_address_set *nb_addr_set;
+NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
+  nb_address_set_table) {
+if (nbrec_address_set_is_new(nb_addr_set) ||
+nbrec_address_set_is_deleted(nb_addr_set)) {
+return false;
+}
+}
+
+struct ovsdb_idl_index *sbrec_address_set_by_name =
+engine_ovsdb_node_get_index(
+engine_get_input("SB_address_set", node),
+"sbrec_address_set_by_name");
+
+NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
+  nb_address_set_table) {
+const struct sbrec_address_set *sb_addr_set =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  nb_addr_set->name);
+if (!sb_addr_set) {
+return false;
+}
+update_sb_addr_set((const char **) nb_addr_set->addresses,
+   nb_addr_set->n_addresses, sb_addr_set);
+}
+
+return true;
+}
+
+bool
+address_set_sync_nb_port_group_handler(struct engine_node *node OVS_UNUSED,
+   void *data OVS_UNUSED)
+{
+const struct nbrec_port_group *nb_pg;
+const struct nbrec_port_group_table *nb_port_group_table =
+EN_OVSDB_GET(engine_get_input("NB_port_group", node));
+NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
+if (nbrec_port_group_is_new(nb_pg) ||
+nbrec_port_group_is_deleted(nb_pg)) {
+return false;
+}
+}
+
+struct ovsdb_idl_index *sbrec_address_set_by_name =
+engine_ovsdb_node_get_index(
+engine_get_input("SB_address_set", node),
+"sbrec_address_set_by_name");
+NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
+char *ipv4_addrs_name = xasprintf("%s_ip4", nb_pg->name);
+const struct sbrec_address_set *sb_addr_set_v4 =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  ipv4_addrs_name);
+if (!sb_addr_set_v4) {
+free(ipv4_addrs_name);
+return false;
+}
+char *ipv6_addrs_name = xasprintf("%s_ip6", nb_pg->name);
+const struct sbrec_address_set *sb_addr_set_v6 =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  ipv6_addrs_name);
+if (!sb_addr_set_v6) {
+free(ipv4_addrs_name);
+  

[ovs-dev] [PATCH ovn v2 2/2] northd: Add I-P for syncing SB address sets.

2022-11-14 Thread numans
From: Numan Siddique 

Updates to NB address sets and NB port groups are handled
incrementally for syncing the SB address sets.  This patch
doesn't support syncing the SB Address sets for the router
load balancer vips incrementally, instead a full recompute is
triggered for any changes to NB load balancers, NB load balancer
groups and NB logical routers.

Signed-off-by: Numan Siddique 
---
 northd/en-sb-sync.c  | 202 ---
 northd/en-sb-sync.h  |   6 ++
 northd/inc-proc-northd.c |  18 +++-
 tests/ovn-northd.at  |  52 ++
 4 files changed, 260 insertions(+), 18 deletions(-)

diff --git a/northd/en-sb-sync.c b/northd/en-sb-sync.c
index c3ba315df..8a17998ec 100644
--- a/northd/en-sb-sync.c
+++ b/northd/en-sb-sync.c
@@ -22,6 +22,7 @@
 #include "openvswitch/util.h"
 
 #include "en-sb-sync.h"
+#include "include/ovn/expr.h"
 #include "lib/inc-proc-eng.h"
 #include "lib/lb.h"
 #include "lib/ovn-nb-idl.h"
@@ -41,6 +42,13 @@ static void sync_address_sets(const struct 
nbrec_address_set_table *,
   const struct sbrec_address_set_table *,
   struct ovsdb_idl_txn *ovnsb_txn,
   struct hmap *datapaths);
+static const struct sbrec_address_set *sb_address_set_lookup_by_name(
+struct ovsdb_idl_index *, const char *name);
+static void update_sb_addr_set(const char **nb_addresses, size_t n_addresses,
+   const struct sbrec_address_set *);
+static void build_port_group_address_set(const struct nbrec_port_group *,
+ struct svec *ipv4_addrs,
+ struct svec *ipv6_addrs);
 
 void *
 en_sb_sync_init(struct engine_node *node OVS_UNUSED,
@@ -94,6 +102,98 @@ en_address_set_sync_cleanup(void *data OVS_UNUSED)
 
 }
 
+bool
+address_set_sync_nb_address_set_handler(struct engine_node *node OVS_UNUSED,
+void *data OVS_UNUSED)
+{
+const struct nbrec_address_set_table *nb_address_set_table =
+EN_OVSDB_GET(engine_get_input("NB_address_set", node));
+
+/* Return false if an address set is created or deleted.
+ * Handle I-P for only updated address sets. */
+const struct nbrec_address_set *nb_addr_set;
+NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
+  nb_address_set_table) {
+if (nbrec_address_set_is_new(nb_addr_set) ||
+nbrec_address_set_is_deleted(nb_addr_set)) {
+return false;
+}
+}
+
+struct ovsdb_idl_index *sbrec_address_set_by_name =
+engine_ovsdb_node_get_index(
+engine_get_input("SB_address_set", node),
+"sbrec_address_set_by_name");
+
+NBREC_ADDRESS_SET_TABLE_FOR_EACH_TRACKED (nb_addr_set,
+  nb_address_set_table) {
+const struct sbrec_address_set *sb_addr_set =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  nb_addr_set->name);
+if (!sb_addr_set) {
+return false;
+}
+update_sb_addr_set((const char **) nb_addr_set->addresses,
+   nb_addr_set->n_addresses, sb_addr_set);
+}
+
+return true;
+}
+
+bool
+address_set_sync_nb_port_group_handler(struct engine_node *node OVS_UNUSED,
+   void *data OVS_UNUSED)
+{
+const struct nbrec_port_group *nb_pg;
+const struct nbrec_port_group_table *nb_port_group_table =
+EN_OVSDB_GET(engine_get_input("NB_port_group", node));
+NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
+if (nbrec_port_group_is_new(nb_pg) ||
+nbrec_port_group_is_deleted(nb_pg)) {
+return false;
+}
+}
+
+struct ovsdb_idl_index *sbrec_address_set_by_name =
+engine_ovsdb_node_get_index(
+engine_get_input("SB_address_set", node),
+"sbrec_address_set_by_name");
+NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_port_group_table) {
+char *ipv4_addrs_name = xasprintf("%s_ip4", nb_pg->name);
+const struct sbrec_address_set *sb_addr_set_v4 =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  ipv4_addrs_name);
+if (!sb_addr_set_v4) {
+free(ipv4_addrs_name);
+return false;
+}
+char *ipv6_addrs_name = xasprintf("%s_ip6", nb_pg->name);
+const struct sbrec_address_set *sb_addr_set_v6 =
+sb_address_set_lookup_by_name(sbrec_address_set_by_name,
+  ipv6_addrs_name);
+if (!sb_addr_set_v6) {
+free(ipv4_addrs_name);
+free(ipv6_addrs_name);
+return false;
+}
+
+struct svec ipv4_addrs =