On Tue, Jul 7, 2026 at 2:16 AM Dumitru Ceara <[email protected]> wrote: > > Hi Sragdhara, > > On 7/1/26 10:52 PM, Sragdhara Datta Chaudhuri wrote: > > Hi Dumitru, Numan, > > > > Sorry for the delay in responding. Let me try to explain our use case. > > > > > > The motivation is to support cross AZ security policies, where the secured > > entity is in zone1 but the src/dst endpoints are in zone2. > > > > Say you are applying a “to-port” ACL to a port-group in zone1, and you want > > to deny traffic from a set of source endpoints that are in zone2. One way > > would be to have some out-of-band mechanism whereby the zone1 CMS in > > figures out the IP addresses of these endpoints in zone2 and creates an > > address-set locally in zone1 (and keeps it updated with any changes in the > > AS membership in the remote zone). We thought it would be better to provide > > a solution based on the already available sync mechanism of OVN-IC. > > > > I think that I'm OK with that but I'll let Numan pitch in to make sure > his question was answered.
No objections. Numan > > > * The OVN control plane in zone2 creates and maintains an address-set > > AS1 with IPs of the interesting entities (e.g. based on pod label or VM > > tags). > > * This address-set gets synced to zone1 via IC > > * The OVN control plane in zone1 creates ACL for a local port-group > > with source as AS1. > > > > Regarding syncing remote zone’s port-group, the ACL match based on “inport” > > or “outport” can be done only for local ports managed by the OVN control > > plane of this zone and learning about remote zone’s ports may not be useful > > in this context. > > Well, if the ACL is applied on the transit switch, it could match on > remote "inport"/"outport" without any issues. > > So we could also sync port groups that include transit switch ports IMO. > > Regards, > Dumitru > > > > > Thanks, > > Sragdhara > > > > > > From: Dumitru Ceara <[email protected]> > > Date: Monday, June 22, 2026 at 5:07 AM > > To: Numan Siddique <[email protected]>; Sragdhara Datta Chaudhuri > > <[email protected]> > > Cc: [email protected] <[email protected]> > > Subject: Re: [ovs-dev] [PATCH OVN v1] ovn-ic: Address set synchronization > > across AZs. > > > > !-------------------------------------------------------------------| > > CAUTION: External Email > > > > |-------------------------------------------------------------------! > > > > On 6/11/26 12:57 AM, Numan Siddique wrote: > >> On Sun, May 17, 2026 at 11:20 PM Sragdhara Datta Chaudhuri < > >> [email protected]> wrote: > >> > >>> Advertise address_set from one AZ to others via ovn-ic. > >>> The address sets from SB are advertised to the IC-SB Address_Set. > >>> The address sets from IC SB that belong to remote AZ are synced > >>> to the local NB Address_Set. > >>> > >>> A new table Address_Set has been added to IC-SB. > >>> "Address_Set": { > >>> "columns": { > >>> "name": {"type": "string"}, > >>> "addresses": {"type": {"key": "string", > >>> "min": 0, > >>> "max": "unlimited"}}, > >>> "availability_zone": {"type": {"key": {"type": "uuid", > >>> "refTable": "Availability_Zone"}}}, > >>> "external_ids": { > >>> "type": {"key": "string", "value": "string", > >>> "min": 0, "max": "unlimited"}}}, > >>> "indexes": [["name"]], > >>> "isRoot": true} > >>> } > >>> > >>> New "options" field has been added to NB Address_Set table. > >>> ic-adv - A boolean value that enables advertisement of this > >>> Address_Set to IC-SB. Default is false. > >>> New "options" field has been added to SB Address_Set table. > >>> The options from NB Address_Set gets synced to the SB entry. > >>> > >>> Two new nb_global options have been added: > >>> ic-as-adv - If this is set to true, the Address_Sets in this AZ that have > >>> option ic-adv set to true get advertised to the IC-SB. > >>> Default is false. > >>> ic-as-learn - If this is set to true, the Address_Sets in IC-SB get > >>> synced to the NB Address_Set table of this AZ. Default > >>> value of the option is false. The synced address_sets > >>> would have external-id "ic-learnt" set to true. > >>> > >>> The existing northd code that syncs Address_Set from NB to SB has been > >>> enhanced to sync "options". > >>> > >>> New logic has been added in ovn-ic to sync address sets with IC-SB. > >>> Advertise logic (from SB to IC-SB): > >>> - Each SB address set that needs to be advertised (ic-adv option set), > >>> check if it is already present in IC-SB. If not, create new entry in > >>> IC-SB. Otherwise sync addresses from local address set to IC-SB entry. > >>> - Delete extra address sets in IC-SB that were earlier learnt from this > >>> AZ, but is no longer present, or not enabled for advertisement. > >>> > >>> Learning logic (from IC-SB to NB): > >>> - For each NB Address set entries that were earlier learnt from IC-SB > >>> (external-id "ic-learnt" set to true), check if it is still present > >>> in IC-SB. If not, delete local entry in NB. If yes, sync addresses > >>> from IC-SB to NB. > >>> - Any remote address sets in IC-SB (AZ not same as local AZ) that is not > >>> present in local AZ, create local entry in NB with external-id > >>> "ic-learnt" set to true. > >>> > >>> Signed-off-by: Sragdhara Datta Chaudhuri <[email protected]> > >>> Acked-by: Priyankar Jain <[email protected]> > >>> > >> > >> Hi Sragdhara, > >> > > > > Hi Sragdhara, Numan, > > > >> What is the motivation for this patch ? > >> Technically speaking CMS can create the Address sets on the desired AZ NB > >> DBs right ? > >> > >> Is the main motivation the operational ease for CMS ? > >> > > > > +1 to Numan's question. > > > > Also, if we sync Address_Sets why not also sync Port_Groups? > > > >> Thanks > >> Numan > >> > > > > Regards, > > Dumitru > > > >> --- > >>> ic/inc-proc-ic.c | 12 ++- > >>> ic/ovn-ic.c | 188 ++++++++++++++++++++++++++++++++++++++++++++ > >>> northd/en-sync-sb.c | 35 +++++++-- > >>> ovn-ic-sb.ovsschema | 17 +++- > >>> ovn-ic-sb.xml | 26 ++++++ > >>> ovn-nb.ovsschema | 9 ++- > >>> ovn-nb.xml | 31 ++++++++ > >>> ovn-sb.ovsschema | 9 ++- > >>> ovn-sb.xml | 4 + > >>> tests/ovn-ic.at | 172 ++++++++++++++++++++++++++++++++++++++++ > >>> 10 files changed, 486 insertions(+), 17 deletions(-) > >>> > >>> diff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c > >>> index 2c0420292..bbcbcdd17 100644 > >>> --- a/ic/inc-proc-ic.c > >>> +++ b/ic/inc-proc-ic.c > >>> @@ -41,7 +41,8 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic); > >>> NB_NODE(logical_switch, "logical_switch") \ > >>> NB_NODE(logical_switch_port, "logical_switch_port") \ > >>> NB_NODE(load_balancer, "load_balancer") \ > >>> - NB_NODE(load_balancer_group, "load_balancer_group") > >>> + NB_NODE(load_balancer_group, "load_balancer_group") \ > >>> + NB_NODE(address_set, "address_set") > >>> > >>> enum nb_engine_node { > >>> #define NB_NODE(NAME, NAME_STR) NB_##NAME, > >>> @@ -66,7 +67,8 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic); > >>> SB_NODE(datapath_binding, "datapath_binding") \ > >>> SB_NODE(port_binding, "port_binding") \ > >>> SB_NODE(service_monitor, "service_monitor") \ > >>> - SB_NODE(learned_route, "learned_route") > >>> + SB_NODE(learned_route, "learned_route") \ > >>> + SB_NODE(address_set, "address_set") > >>> > >>> enum sb_engine_node { > >>> #define SB_NODE(NAME, NAME_STR) SB_##NAME, > >>> @@ -114,7 +116,8 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic); > >>> ICSB_NODE(datapath_binding, "datapath_binding") \ > >>> ICSB_NODE(encap, "encap") \ > >>> ICSB_NODE(gateway, "gateway") \ > >>> - ICSB_NODE(port_binding, "port_binding") > >>> + ICSB_NODE(port_binding, "port_binding") \ > >>> + ICSB_NODE(address_set, "address_set") > >>> > >>> enum icsb_engine_node { > >>> #define ICSB_NODE(NAME, NAME_STR) ICSB_##NAME, > >>> @@ -176,6 +179,7 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb, > >>> engine_add_input(&en_ic, &en_nb_logical_switch_port, NULL); > >>> engine_add_input(&en_ic, &en_nb_load_balancer, NULL); > >>> engine_add_input(&en_ic, &en_nb_load_balancer_group, NULL); > >>> + engine_add_input(&en_ic, &en_nb_address_set, NULL); > >>> > >>> engine_add_input(&en_ic, &en_sb_sb_global, NULL); > >>> engine_add_input(&en_ic, &en_sb_chassis, NULL); > >>> @@ -184,6 +188,7 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb, > >>> engine_add_input(&en_ic, &en_sb_port_binding, NULL); > >>> engine_add_input(&en_ic, &en_sb_service_monitor, NULL); > >>> engine_add_input(&en_ic, &en_sb_learned_route, NULL); > >>> + engine_add_input(&en_ic, &en_sb_address_set, NULL); > >>> > >>> engine_add_input(&en_ic, &en_icnb_ic_nb_global, NULL); > >>> engine_add_input(&en_ic, &en_icnb_transit_switch, NULL); > >>> @@ -198,6 +203,7 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb, > >>> engine_add_input(&en_ic, &en_icsb_gateway, NULL); > >>> engine_add_input(&en_ic, &en_icsb_route, NULL); > >>> engine_add_input(&en_ic, &en_icsb_datapath_binding, NULL); > >>> + engine_add_input(&en_ic, &en_icsb_address_set, NULL); > >>> > >>> struct engine_arg engine_arg = { > >>> .nb_idl = nb->idl, > >>> diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c > >>> index ba9490658..c1718cca8 100644 > >>> --- a/ic/ovn-ic.c > >>> +++ b/ic/ovn-ic.c > >>> @@ -526,6 +526,173 @@ sync_sb_gw_to_isb(struct ic_context *ctx, > >>> free(isb_encaps); > >>> } > >>> > >>> +static void > >>> +nb_addr_set_apply_diff(const void *arg, const char *item, bool add) > >>> +{ > >>> + const struct nbrec_address_set *as = arg; > >>> + if (add) { > >>> + nbrec_address_set_update_addresses_addvalue(as, item); > >>> + } else { > >>> + nbrec_address_set_update_addresses_delvalue(as, item); > >>> + } > >>> +} > >>> + > >>> +static void > >>> +update_nb_addr_set(const struct icsbrec_address_set *icsb_as, > >>> + const struct nbrec_address_set *nb_as) > >>> +{ > >>> + struct sorted_array nb_addrs = > >>> + sorted_array_from_dbrec(nb_as, addresses); > >>> + struct sorted_array icsb_addrs = > >>> + sorted_array_from_dbrec(icsb_as, addresses); > >>> + sorted_array_apply_diff(&icsb_addrs, &nb_addrs, > >>> + nb_addr_set_apply_diff, nb_as); > >>> + sorted_array_destroy(&icsb_addrs); > >>> + sorted_array_destroy(&nb_addrs); > >>> +} > >>> + > >>> +static void > >>> +icsb_addr_set_apply_diff(const void *arg, const char *item, bool add) > >>> +{ > >>> + const struct icsbrec_address_set *as = arg; > >>> + if (add) { > >>> + icsbrec_address_set_update_addresses_addvalue(as, item); > >>> + } else { > >>> + icsbrec_address_set_update_addresses_delvalue(as, item); > >>> + } > >>> +} > >>> + > >>> +static void > >>> +update_icsb_addr_set(struct sorted_array *nb_addrs, > >>> + const struct icsbrec_address_set *icsb_as) > >>> +{ > >>> + struct sorted_array icsb_addrs = > >>> + sorted_array_from_dbrec(icsb_as, addresses); > >>> + sorted_array_apply_diff(nb_addrs, &icsb_addrs, > >>> + icsb_addr_set_apply_diff, icsb_as); > >>> + sorted_array_destroy(&icsb_addrs); > >>> +} > >>> + > >>> +static void > >>> +sync_addr_set_to_icsb(struct ovsdb_idl_txn *ovnisb_txn, > >>> + const struct sbrec_address_set *sb_as, > >>> + const struct icsbrec_address_set *icsb_as, > >>> + const struct icsbrec_availability_zone *az) > >>> +{ > >>> + struct sorted_array addrs = > >>> + sorted_array_from_dbrec(sb_as, addresses); > >>> + if (!icsb_as) { > >>> + icsb_as = icsbrec_address_set_insert(ovnisb_txn); > >>> + icsbrec_address_set_set_name(icsb_as, sb_as->name); > >>> + icsbrec_address_set_set_availability_zone(icsb_as, az); > >>> + icsbrec_address_set_set_addresses(icsb_as, addrs.arr, addrs.n); > >>> + } else { > >>> + update_icsb_addr_set(&addrs, icsb_as); > >>> + } > >>> + sorted_array_destroy(&addrs); > >>> +} > >>> + > >>> +static void > >>> +sync_addr_set_from_icsb(struct ovsdb_idl_txn *ovnnb_txn, > >>> + const struct icsbrec_address_set *icsb_as) > >>> +{ > >>> + struct nbrec_address_set *nb_as; > >>> + struct sorted_array addrs = > >>> + sorted_array_from_dbrec(icsb_as, addresses); > >>> + > >>> + nb_as = nbrec_address_set_insert(ovnnb_txn); > >>> + nbrec_address_set_set_name(nb_as, icsb_as->name); > >>> + nbrec_address_set_update_external_ids_setkey(nb_as, "ic-learnt", > >>> "true"); > >>> + nbrec_address_set_set_addresses(nb_as, addrs.arr, addrs.n); > >>> + sorted_array_destroy(&addrs); > >>> +} > >>> + > >>> +static void > >>> +address_set_run(struct ic_context *ctx) > >>> +{ > >>> + if (!ctx->ovnisb_unlocked_txn || !ctx->ovnnb_txn || !ctx->ovnsb_txn) > >>> { > >>> + return; > >>> + } > >>> + > >>> + struct shash ic_local_as = SHASH_INITIALIZER(&ic_local_as); > >>> + struct shash ic_remote_as = SHASH_INITIALIZER(&ic_remote_as); > >>> + const struct icsbrec_address_set *ic_as; > >>> + ICSBREC_ADDRESS_SET_FOR_EACH (ic_as, ctx->ovnisb_unlocked_idl) { > >>> + if (ic_as->availability_zone == ctx->runned_az) { > >>> + shash_add(&ic_local_as, ic_as->name, ic_as); > >>> + } else { > >>> + shash_add(&ic_remote_as, ic_as->name, ic_as); > >>> + } > >>> + } > >>> + > >>> + const struct nbrec_nb_global *nb_global = > >>> + nbrec_nb_global_first(ctx->ovnnb_idl); > >>> + ovs_assert(nb_global); > >>> + bool global_learn = smap_get_bool(&nb_global->options, "ic-as-learn", > >>> + false); > >>> + bool global_adv = smap_get_bool(&nb_global->options, "ic-as-adv", > >>> false); > >>> + > >>> + /* Advertise address set - from SB to IC-SB: > >>> + * - Each SB address set that needs to be advertised (ic-adv option > >>> set), > >>> + * check if it is already present in IC-SB. If not, create new entry > >>> in > >>> + * IC-SB. Otherwise sync addresses from local address set to IC-SB > >>> entry. > >>> + * - Delete extra address sets in IC-SB that were earlier learnt from > >>> this > >>> + * AZ, but is no longer present, or not enabled for advertisement. > >>> + */ > >>> + if (global_adv) { > >>> + const struct sbrec_address_set *sb_as; > >>> + SBREC_ADDRESS_SET_FOR_EACH (sb_as, ctx->ovnsb_idl) { > >>> + if (smap_get_bool(&sb_as->options, "ic-adv", false)) { > >>> + const struct icsbrec_address_set *icsb_as; > >>> + icsb_as = shash_find_and_delete(&ic_local_as, > >>> sb_as->name); > >>> + sync_addr_set_to_icsb(ctx->ovnisb_unlocked_txn, sb_as, > >>> icsb_as, > >>> + ctx->runned_az); > >>> + } > >>> + } > >>> + } > >>> + struct shash_node *node; > >>> + SHASH_FOR_EACH (node, &ic_local_as) { > >>> + icsbrec_address_set_delete(node->data); > >>> + } > >>> + shash_destroy(&ic_local_as); > >>> + > >>> + /* Learn address set - from IC-SB to NB: > >>> + * - For each NB Address set entries that were earlier learnt from > >>> IC-SB > >>> + * (external-id "ic-learnt" set to true), check if it is still > >>> present > >>> + * in IC-SB. If not, delete local entry in NB. If yes, sync > >>> addresses > >>> + * from IC-SB to NB. > >>> + * - Any remote address sets in IC-SB (AZ not same as local AZ) that > >>> is not > >>> + * present in local AZ, create local entry in NB with external-id > >>> + * "ic-learnt" set to true. > >>> + */ > >>> + const struct nbrec_address_set *nb_as; > >>> + NBREC_ADDRESS_SET_FOR_EACH (nb_as, ctx->ovnnb_idl) { > >>> + const struct icsbrec_address_set *icsb_as; > >>> + icsb_as = shash_find_and_delete(&ic_remote_as, nb_as->name); > >>> + if (smap_get_bool(&nb_as->external_ids, "ic-learnt", false)) { > >>> + if (!icsb_as || !global_learn) { > >>> + nbrec_address_set_delete(nb_as); > >>> + } else { > >>> + update_nb_addr_set(icsb_as, nb_as); > >>> + } > >>> + } > >>> + } > >>> + > >>> + if (global_learn) { > >>> + SHASH_FOR_EACH (node, &ic_remote_as) { > >>> + /* In case local address-set with same name exists, we > >>> + * will not overwrite it because such address sets are > >>> already > >>> + * removed from ic_remote_as in the loop above. > >>> + */ > >>> + if (node->data) { > >>> + sync_addr_set_from_icsb(ctx->ovnnb_txn, node->data); > >>> + } > >>> + } > >>> + } > >>> + shash_destroy(&ic_remote_as); > >>> +} > >>> + > >>> + > >>> static void > >>> gateway_run(struct ic_context *ctx) > >>> { > >>> @@ -3199,6 +3366,7 @@ ovn_db_run(struct ic_context *ctx) > >>> port_binding_run(ctx); > >>> route_run(ctx); > >>> sync_service_monitor(ctx); > >>> + address_set_run(ctx); > >>> > >>> ovn_destroy_tnlids(&dp_tnlids); > >>> shash_destroy(&isb_ts_dps); > >>> @@ -3536,6 +3704,17 @@ main(int argc, char *argv[]) > >>> ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > >>> > >>> &nbrec_load_balancer_group_col_load_balancer); > >>> > >>> + ovsdb_idl_add_table(ovnnb_idl_loop.idl, &nbrec_table_address_set); > >>> + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > >>> + &nbrec_address_set_col_name); > >>> + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > >>> + &nbrec_address_set_col_addresses); > >>> + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > >>> + &nbrec_address_set_col_options); > >>> + ovsdb_idl_track_add_column(ovnnb_idl_loop.idl, > >>> + &nbrec_address_set_col_external_ids); > >>> + > >>> + > >>> /* ovn-sb db. */ > >>> struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( > >>> ovsdb_idl_create(ovnsb_db, &sbrec_idl_class, false, true)); > >>> @@ -3621,6 +3800,15 @@ main(int argc, char *argv[]) > >>> &sbrec_learned_route_col_ip_prefix); > >>> ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > >>> &sbrec_learned_route_col_datapath); > >>> + > >>> + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_address_set); > >>> + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > >>> + &sbrec_address_set_col_name); > >>> + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > >>> + &sbrec_address_set_col_addresses); > >>> + ovsdb_idl_track_add_column(ovnsb_idl_loop.idl, > >>> + &sbrec_address_set_col_options); > >>> + > >>> /* Create IDL indexes */ > >>> struct ovsdb_idl_index *nbrec_ls_by_name > >>> = ovsdb_idl_index_create1(ovnnb_idl_loop.idl, > >>> diff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c > >>> index 0b2a85b3b..b3d96af16 100644 > >>> --- a/northd/en-sync-sb.c > >>> +++ b/northd/en-sync-sb.c > >>> @@ -43,7 +43,8 @@ VLOG_DEFINE_THIS_MODULE(en_sync_to_sb); > >>> > >>> static void sync_addr_set(struct ovsdb_idl_txn *ovnsb_txn, const char > >>> *name, > >>> struct sorted_array *addresses, > >>> - struct shash *sb_address_sets); > >>> + struct shash *sb_address_sets, > >>> + const struct smap *options); > >>> static void sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > >>> const struct nbrec_address_set_table *, > >>> const struct nbrec_port_group_table *, > >>> @@ -118,6 +119,18 @@ en_sync_to_sb_addr_set_cleanup(void *data OVS_UNUSED) > >>> > >>> } > >>> > >>> +static void > >>> +sync_address_set_options(const struct sbrec_address_set *sb_addr_set, > >>> + const struct smap *nb_options) > >>> +{ > >>> + if (!smap_equal(&sb_addr_set->options, nb_options)) { > >>> + struct smap new_options; > >>> + smap_clone(&new_options, nb_options); > >>> + sbrec_address_set_set_options(sb_addr_set, &new_options); > >>> + smap_destroy(&new_options); > >>> + } > >>> +} > >>> + > >>> enum engine_input_handler_result > >>> sync_to_sb_addr_set_nb_address_set_handler(struct engine_node *node, > >>> void *data OVS_UNUSED) > >>> @@ -153,6 +166,7 @@ sync_to_sb_addr_set_nb_address_set_handler(struct > >>> engine_node *node, > >>> sorted_array_from_dbrec(nb_addr_set, addresses); > >>> update_sb_addr_set(&addrs, sb_addr_set); > >>> sorted_array_destroy(&addrs); > >>> + sync_address_set_options(sb_addr_set, &nb_addr_set->options); > >>> } > >>> > >>> return EN_HANDLED_UNCHANGED; > >>> @@ -449,7 +463,8 @@ sync_to_sb_pb_lr_stateful_handler(struct engine_node > >>> *node, > >>> static void > >>> sync_addr_set(struct ovsdb_idl_txn *ovnsb_txn, const char *name, > >>> struct sorted_array *addresses, > >>> - struct shash *sb_address_sets) > >>> + struct shash *sb_address_sets, > >>> + const struct smap *options) > >>> { > >>> const struct sbrec_address_set *sb_address_set; > >>> sb_address_set = shash_find_and_delete(sb_address_sets, > >>> @@ -462,6 +477,9 @@ sync_addr_set(struct ovsdb_idl_txn *ovnsb_txn, const > >>> char *name, > >>> } else { > >>> update_sb_addr_set(addresses, sb_address_set); > >>> } > >>> + if (options) { > >>> + sync_address_set_options(sb_address_set, options); > >>> + } > >>> } > >>> > >>> /* OVN_Southbound Address_Set table contains same records as in north > >>> @@ -500,7 +518,7 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > >>> const char *svc_macs[] = {svc_monitor_macp, svc_monitor_macp_dst}; > >>> struct sorted_array svc = > >>> sorted_array_from_unsorted(svc_macs, ARRAY_SIZE(svc_macs), > >>> false); > >>> - sync_addr_set(ovnsb_txn, "svc_monitor_mac", &svc, &sb_address_sets); > >>> + sync_addr_set(ovnsb_txn, "svc_monitor_mac", &svc, &sb_address_sets, > >>> NULL); > >>> sorted_array_destroy(&svc); > >>> > >>> /* sync port group generated address sets first */ > >>> @@ -519,9 +537,9 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > >>> sorted_array_from_svec(&ipv6_addrs); > >>> > >>> sync_addr_set(ovnsb_txn, ipv4_addrs_name, > >>> - &ipv4_addrs_sorted, &sb_address_sets); > >>> + &ipv4_addrs_sorted, &sb_address_sets, NULL); > >>> sync_addr_set(ovnsb_txn, ipv6_addrs_name, > >>> - &ipv6_addrs_sorted, &sb_address_sets); > >>> + &ipv6_addrs_sorted, &sb_address_sets, NULL); > >>> sorted_array_destroy(&ipv4_addrs_sorted); > >>> sorted_array_destroy(&ipv6_addrs_sorted); > >>> svec_destroy(&ipv4_addrs); > >>> @@ -544,7 +562,7 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > >>> &lr_stateful_rec->lb_ips->ips_v4_reachable); > >>> > >>> sync_addr_set(ovnsb_txn, ipv4_addrs_name, > >>> - &ipv4_addrs_sorted, &sb_address_sets); > >>> + &ipv4_addrs_sorted, &sb_address_sets, NULL); > >>> sorted_array_destroy(&ipv4_addrs_sorted); > >>> free(ipv4_addrs_name); > >>> } > >>> @@ -556,7 +574,7 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > >>> &lr_stateful_rec->lb_ips->ips_v6_reachable); > >>> > >>> sync_addr_set(ovnsb_txn, ipv6_addrs_name, > >>> - &ipv6_addrs_sorted, &sb_address_sets); > >>> + &ipv6_addrs_sorted, &sb_address_sets, NULL); > >>> sorted_array_destroy(&ipv6_addrs_sorted); > >>> free(ipv6_addrs_name); > >>> } > >>> @@ -570,7 +588,8 @@ sync_addr_sets(struct ovsdb_idl_txn *ovnsb_txn, > >>> struct sorted_array addrs = > >>> sorted_array_from_dbrec(nb_address_set, addresses); > >>> sync_addr_set(ovnsb_txn, nb_address_set->name, > >>> - &addrs, &sb_address_sets); > >>> + &addrs, &sb_address_sets, > >>> + &nb_address_set->options); > >>> sorted_array_destroy(&addrs); > >>> } > >>> > >>> diff --git a/ovn-ic-sb.ovsschema b/ovn-ic-sb.ovsschema > >>> index e0e0fef5e..dd1b2533c 100644 > >>> --- a/ovn-ic-sb.ovsschema > >>> +++ b/ovn-ic-sb.ovsschema > >>> @@ -1,7 +1,7 @@ > >>> { > >>> "name": "OVN_IC_Southbound", > >>> - "version": "2.5.0", > >>> - "cksum": "1892994110 9713", > >>> + "version": "2.6.0", > >>> + "cksum": "3333694935 10343", > >>> "tables": { > >>> "IC_SB_Global": { > >>> "columns": { > >>> @@ -192,6 +192,19 @@ > >>> "external_ids": { > >>> "type": {"key": "string", "value": "string", > >>> "min": 0, "max": "unlimited"}}}, > >>> + "isRoot": true}, > >>> + "Address_Set": { > >>> + "columns": { > >>> + "name": {"type": "string"}, > >>> + "addresses": {"type": {"key": "string", > >>> + "min": 0, > >>> + "max": "unlimited"}}, > >>> + "availability_zone": {"type": {"key": {"type": "uuid", > >>> + "refTable": "Availability_Zone"}}}, > >>> + "external_ids": { > >>> + "type": {"key": "string", "value": "string", > >>> + "min": 0, "max": "unlimited"}}}, > >>> + "indexes": [["name"]], > >>> "isRoot": true} > >>> } > >>> } > >>> diff --git a/ovn-ic-sb.xml b/ovn-ic-sb.xml > >>> index f30760100..4fe491fac 100644 > >>> --- a/ovn-ic-sb.xml > >>> +++ b/ovn-ic-sb.xml > >>> @@ -775,4 +775,30 @@ > >>> Copy from source SBDB record. > >>> </column> > >>> </table> > >>> + > >>> + <table name="Address_Set" title="Address Sets"> > >>> + <p> > >>> + Each row in this table represents an Address_Set advertised. > >>> + </p> > >>> + > >>> + <column name="name"> > >>> + A name for the address set. Names are ASCII and must match > >>> + <code>[a-zA-Z_.][a-zA-Z_.0-9]*</code>. > >>> + </column> > >>> + > >>> + <column name="addresses"> > >>> + The set of addresses in string form. > >>> + </column> > >>> + > >>> + <column name="availability_zone"> > >>> + The availability zone that has advertised the Address_Set. > >>> + </column> > >>> + > >>> + <group title="Common Columns"> > >>> + <column name="external_ids"> > >>> + See <em>External IDs</em> at the beginning of this document. > >>> + </column> > >>> + </group> > >>> + </table> > >>> + > >>> </database> > >>> diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema > >>> index e5945b831..00909fff4 100644 > >>> --- a/ovn-nb.ovsschema > >>> +++ b/ovn-nb.ovsschema > >>> @@ -1,7 +1,7 @@ > >>> { > >>> "name": "OVN_Northbound", > >>> - "version": "7.18.0", > >>> - "cksum": "1537030958 45190", > >>> + "version": "7.18.1", > >>> + "cksum": "2442107800 45407", > >>> "tables": { > >>> "NB_Global": { > >>> "columns": { > >>> @@ -292,6 +292,11 @@ > >>> "addresses": {"type": {"key": "string", > >>> "min": 0, > >>> "max": "unlimited"}}, > >>> + "options": { > >>> + "type": {"key": "string", > >>> + "value": "string", > >>> + "min": 0, > >>> + "max": "unlimited"}}, > >>> "external_ids": { > >>> "type": {"key": "string", "value": "string", > >>> "min": 0, "max": "unlimited"}}}, > >>> diff --git a/ovn-nb.xml b/ovn-nb.xml > >>> index 2e8a6a6f1..d98f3244d 100644 > >>> --- a/ovn-nb.xml > >>> +++ b/ovn-nb.xml > >>> @@ -583,6 +583,25 @@ > >>> </column> > >>> </group> > >>> > >>> + <group title="Options for interconnection address_set > >>> advertisement"> > >>> + <p> > >>> + These options control whether address_sets propagate from one > >>> OVN > >>> + deployment to another via the global <ref > >>> db="OVN_IC_Southbound"/>. > >>> + </p> > >>> + > >>> + <column name="options" key="ic-as-adv"> > >>> + A boolean value that enables address_set advertisement to the > >>> global > >>> + <ref db="OVN_IC_Southbound"/> database. Default is > >>> + <code>false</code>. > >>> + </column> > >>> + > >>> + <column name="options" key="ic-as-learn"> > >>> + A boolean value that enables address_set learning from the > >>> global > >>> + <ref db="OVN_IC_Southbound"/> database. Default is > >>> + <code>false</code>. > >>> + </column> > >>> + </group> > >>> + > >>> </group> > >>> > >>> <group title="Connection Options"> > >>> @@ -2409,6 +2428,18 @@ > >>> See <em>External IDs</em> at the beginning of this document. > >>> </column> > >>> </group> > >>> + > >>> + <group title="Common options"> > >>> + <column name="options"> > >>> + This column provides general key/value settings. The supported > >>> + options are described individually below. > >>> + </column> > >>> + > >>> + <column name="options" key="ic-adv"> > >>> + A boolean value that enables advertisement of this Address_Set to > >>> + the global OVN_IC_Southbound database. Default is false. > >>> + </column> > >>> + </group> > >>> </table> > >>> > >>> <table name="Port_Group" title="Port Groups"> > >>> diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema > >>> index d9a91739c..7057178ce 100644 > >>> --- a/ovn-sb.ovsschema > >>> +++ b/ovn-sb.ovsschema > >>> @@ -1,7 +1,7 @@ > >>> { > >>> "name": "OVN_Southbound", > >>> "version": "21.8.0", > >>> - "cksum": "614397313 36713", > >>> + "cksum": "2227484712 36930", > >>> "tables": { > >>> "SB_Global": { > >>> "columns": { > >>> @@ -77,7 +77,12 @@ > >>> "name": {"type": "string"}, > >>> "addresses": {"type": {"key": "string", > >>> "min": 0, > >>> - "max": "unlimited"}}}, > >>> + "max": "unlimited"}}, > >>> + "options": { > >>> + "type": {"key": "string", > >>> + "value": "string", > >>> + "min": 0, > >>> + "max": "unlimited"}}}, > >>> "indexes": [["name"]], > >>> "isRoot": true}, > >>> "Port_Group": { > >>> diff --git a/ovn-sb.xml b/ovn-sb.xml > >>> index 46568da62..51c16600d 100644 > >>> --- a/ovn-sb.xml > >>> +++ b/ovn-sb.xml > >>> @@ -588,6 +588,10 @@ > >>> > >>> <column name="name"/> > >>> <column name="addresses"/> > >>> + <group title="Common Columns"> > >>> + <column name="options"> > >>> + </column> > >>> + </group> > >>> </table> > >>> > >>> <table name="Port_Group" title="Port Groups"> > >>> diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at > >>> index 0fa7c4f29..45f64e551 100644 > >>> --- a/tests/ovn-ic.at > >>> +++ b/tests/ovn-ic.at > >>> @@ -487,6 +487,178 @@ OVN_CLEANUP_IC([az1], [az2]) > >>> AT_CLEANUP > >>> ]) > >>> > >>> +OVN_FOR_EACH_NORTHD([ > >>> +AT_SETUP([ovn-ic -- address-set sync]) > >>> + > >>> +ovn_init_ic_db > >>> +ovn-ic-nbctl ts-add ts1 > >>> + > >>> +for i in 1 2; do > >>> + ovn_start az$i > >>> + ovn_as az$i > >>> + check ovn-ic-nbctl --wait=sb sync > >>> + # Enable address-set learning at AZ level > >>> + check ovn-nbctl set nb_global . options:ic-as-learn=true > >>> + # Enable address-set advertising at AZ level > >>> + check ovn-nbctl set nb_global . options:ic-as-adv=true > >>> + > >>> + # Create address-set to advertise > >>> + check_uuid ovn-nbctl create Address_Set name=az$i-as1 > >>> addresses=\"$i.1.1.1\",\"$i.1.1.2\" options:ic-adv=true > >>> +done > >>> + > >>> +wait_row_count ic-sb:Address_Set 2 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az1-as1], [0], [dnl > >>> +addresses : [["1.1.1.1", "1.1.1.2"]] > >>> +]) > >>> + > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az2-as1], [0], [dnl > >>> +addresses : [["2.1.1.1", "2.1.1.2"]] > >>> +]) > >>> + > >>> +for i in 1 2; do > >>> + OVS_WAIT_UNTIL([ovn_as az$i ovn-nbctl list Address_Set | grep > >>> learnt]) > >>> +done > >>> + > >>> +AT_CHECK([ovn_as az1 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az2-as1], [0], [dnl > >>> +addresses : [["2.1.1.1", "2.1.1.2"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> + > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az1-as1], [0], [dnl > >>> +addresses : [["1.1.1.1", "1.1.1.2"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> + > >>> +# Update AZ1 address_set (add 2 new IPs and delete one) and check it is > >>> synced to IC and AZ2. > >>> +ovn_as az1 ovn-nbctl set Address_Set az1-as1 > >>> addresses=\"1.1.1.1\",\"1.1.1.3\",\"1.1.1.4\" > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az1-as1], [0], [dnl > >>> +addresses : [["1.1.1.1", "1.1.1.3", "1.1.1.4"]] > >>> +]) > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az1-as1], [0], [dnl > >>> +addresses : [["1.1.1.1", "1.1.1.3", "1.1.1.4"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> + > >>> +# Add 2 new address-sets in AZ1 - one to advertise, another not to. > >>> +ovn_as az1 ovn-nbctl create Address_Set name=az1-as2 > >>> addresses=\"1.1.2.1\",\"1.1.2.2\" options:ic-adv=true > >>> +ovn_as az1 ovn-nbctl create Address_Set name=az1-as3 > >>> addresses=\"1.1.3.1\",\"1.1.3.2\" > >>> +wait_row_count ic-sb:Address_Set 3 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az1-as2], [0], [dnl > >>> +addresses : [["1.1.2.1", "1.1.2.2"]] > >>> +]) > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az1-as3], [0], [dnl > >>> +]) > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az1-as2], [0], [dnl > >>> +addresses : [["1.1.2.1", "1.1.2.2"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids find > >>> Address_Set name=az1-as3], [0], [dnl > >>> +]) > >>> + > >>> +# Now set the option field of the above address-set to advertise it. > >>> +ovn_as az1 ovn-nbctl set Address_Set az1-as3 options={ic-adv=true} > >>> +wait_row_count ic-sb:Address_Set 4 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az1-as3], [0], [dnl > >>> +addresses : [["1.1.3.1", "1.1.3.2"]] > >>> +]) > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az1-as3], [0], [dnl > >>> +addresses : [["1.1.3.1", "1.1.3.2"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> + > >>> +# Change the options of one of the address-sets to not advertise. > >>> +ovn_as az1 ovn-nbctl set Address_Set az1-as2 options={ic-adv=false} > >>> +wait_row_count ic-sb:Address_Set 3 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az1-as2], [0], [dnl > >>> +]) > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids find > >>> Address_Set name=az1-as2], [0], [dnl > >>> +]) > >>> + > >>> +# Delete one of the advertised address-sets in AZ1. > >>> +ovn_as az1 ovn-nbctl destroy Address_Set az1-as3 > >>> +wait_row_count ic-sb:Address_Set 2 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az1-as3], [0], [dnl > >>> +]) > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids find > >>> Address_Set name=az1-as3], [0], [dnl > >>> +]) > >>> + > >>> +# Add an IPv6 address-set in AZ2. > >>> +ovn_as az2 ovn-nbctl create Address_Set name=az2-as2 > >>> addresses=\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\",\"2001:0db8:85a3:0000:0000:8a2e:0370:7335\" > >>> options:ic-adv=true > >>> +wait_row_count ic-sb:Address_Set 3 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az2-as2], [0], [dnl > >>> +addresses : [["2001:0db8:85a3:0000:0000:8a2e:0370:7334", > >>> "2001:0db8:85a3:0000:0000:8a2e:0370:7335"]] > >>> +]) > >>> +AT_CHECK([ovn_as az1 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az2-as2], [0], [dnl > >>> +addresses : [["2001:0db8:85a3:0000:0000:8a2e:0370:7334", > >>> "2001:0db8:85a3:0000:0000:8a2e:0370:7335"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> + > >>> +# Set the global option in AZ1 to not learn. > >>> +ovn_as az1 ovn-nbctl set nb_global . options:ic-as-learn=false > >>> +OVS_WAIT_WHILE([ovn_as az1 ovn-nbctl list Address_Set | grep learnt]) > >>> +ovn_as az1 wait_row_count nb:Address_Set 2 > >>> + > >>> +# Set the global option in AZ1 back to learn. > >>> +ovn_as az1 ovn-nbctl set nb_global . options:ic-as-learn=true > >>> +OVS_WAIT_UNTIL([ovn_as az1 ovn-nbctl list Address_Set | grep learnt]) > >>> +ovn_as az1 wait_row_count nb:Address_Set 4 > >>> +AT_CHECK([ovn_as az1 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az2-as2], [0], [dnl > >>> +addresses : [["2001:0db8:85a3:0000:0000:8a2e:0370:7334", > >>> "2001:0db8:85a3:0000:0000:8a2e:0370:7335"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> +AT_CHECK([ovn_as az1 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az2-as1], [0], [dnl > >>> +addresses : [["2.1.1.1", "2.1.1.2"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> + > >>> +# Set the global option in AZ2 to not advertise. > >>> +ovn_as az2 ovn-nbctl set nb_global . options:ic-as-adv=false > >>> +wait_row_count ic-sb:Address_Set 1 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az2-as1], [0], [dnl]) > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az2-as2], [0], [dnl]) > >>> +OVS_WAIT_WHILE([ovn_as az1 ovn-nbctl list Address_Set | grep learnt]) > >>> + > >>> +# Set the global option in AZ2 back to advertise. > >>> +ovn_as az2 ovn-nbctl set nb_global . options:ic-as-adv=true > >>> +wait_row_count ic-sb:Address_Set 3 > >>> +ovn_as az1 wait_row_count nb:Address_Set 4 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az2-as1], [0], [dnl > >>> +addresses : [["2.1.1.1", "2.1.1.2"]] > >>> +]) > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set > >>> name=az2-as2], [0], [dnl > >>> +addresses : [["2001:0db8:85a3:0000:0000:8a2e:0370:7334", > >>> "2001:0db8:85a3:0000:0000:8a2e:0370:7335"]] > >>> +]) > >>> +AT_CHECK([ovn_as az1 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az2-as1], [0], [dnl > >>> +addresses : [["2.1.1.1", "2.1.1.2"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> +AT_CHECK([ovn_as az1 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set az2-as2], [0], [dnl > >>> +addresses : [["2001:0db8:85a3:0000:0000:8a2e:0370:7334", > >>> "2001:0db8:85a3:0000:0000:8a2e:0370:7335"]] > >>> +external_ids : {ic-learnt="true"} > >>> +]) > >>> + > >>> +# Create an address-set in AZ1 and then try to advertise an address-set > >>> with same name from AZ2. > >>> +# It will sync to IC-SB but will not propagate to AZ1. > >>> +ovn_as az1 ovn-nbctl create Address_Set name=dup-as addresses=\"5.5.5.1\" > >>> +ovn_as az2 ovn-nbctl create Address_Set name=dup-as addresses=\"5.5.5.2\" > >>> options:ic-adv=true > >>> +wait_row_count ic-sb:Address_Set 4 > >>> +AT_CHECK([ovn-ic-sbctl --columns=addresses find Address_Set name=dup-as], > >>> [0], [dnl > >>> +addresses : [["5.5.5.2"]] > >>> +]) > >>> +AT_CHECK([ovn_as az1 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set dup-as], [0], [dnl > >>> +addresses : [["5.5.5.1"]] > >>> +external_ids : {} > >>> +]) > >>> +AT_CHECK([ovn_as az2 ovn-nbctl --columns=addresses,external_ids list > >>> Address_Set dup-as], [0], [dnl > >>> +addresses : [["5.5.5.2"]] > >>> +external_ids : {} > >>> +]) > >>> + > >>> +OVN_CLEANUP_IC([az1], [az2]) > >>> + > >>> +AT_CLEANUP > >>> +]) > >>> + > >>> OVN_FOR_EACH_NORTHD([ > >>> AT_SETUP([ovn-ic -- route sync]) > >>> > >>> -- > >>> 2.39.3 > >>> > >>> _______________________________________________ > >>> dev mailing list > >>> [email protected] > >>> https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=uXnTjPDrt8WYa8nbZqANTqL0TyzFTTKpPHphGFPgvBw&m=Sfq6W1O4ZvoTY48n5rYG-E4genNM9pYjs8B9yiomtXDlWouZwnBaHbur_Fwv1T_d&s=XhNdbV4XPSyYtQUneG3Qvv1IenY1xm2_83PENBDh2Us&e= > >>> > >> _______________________________________________ > >> dev mailing list > >> [email protected] > >> https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwIDaQ&c=s883GpUCOChKOHiocYtGcg&r=uXnTjPDrt8WYa8nbZqANTqL0TyzFTTKpPHphGFPgvBw&m=Sfq6W1O4ZvoTY48n5rYG-E4genNM9pYjs8B9yiomtXDlWouZwnBaHbur_Fwv1T_d&s=XhNdbV4XPSyYtQUneG3Qvv1IenY1xm2_83PENBDh2Us&e= > >> > > > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
