Hi Dumitru! Thanks for the review!
I will correct your comments regarding the need to remove checks for 
zero returned arguments. Regarding the MAC address check - I'll fix that 
too. thanks! I'll send you the patch as soon as possible. do you have 
any comments regarding the other patches in this patch series?

On 18.08.2025 16:19, Dumitru Ceara wrote:
> On 8/15/25 10:06 AM, Alexandra Rukomoinikova wrote:
>> This commit adds support for synchronizing load balancer health checks
>> across interconnected availability zones via OVN-IC. Key features include:
>>
>> 1. Added new Service_Monitor table to ICSB database
>>     - Tracks service monitors across AZs with source/target zone info
>>     - Supports status propagation between zones
>>
>> 2. Implemented synchronization logic in ovn-ic:
>>     - Pushes local service monitors to remote AZs via ICSB
>>     - Pulls remote monitors into local SBDB as IC-learned
>>     - Handles status updates in both directions
>>     - Maintains consistency during configuration changes
>>
>> 3. Added comprehensive test casesю
>>
>> 4. Extended OVSDB indexes for efficient lookups.
>>
>> Signed-off-by: Alexandra Rukomoinikova <arukomoinikova@k2.cloud>
>> ---
>> v1 --> v2: 1) added test for parsing ip_port_mapping for ipv4
>>         2) corrected comments regarding tests
>> ---
> Hi Alexandra,
>
> I know the patch was merged but I think we might need some small follow
> ups, please see below.
>
>>   ic/ovn-ic.c         | 503 ++++++++++++++++++++++++++++++++++++++++++++
>>   ovn-ic-sb.ovsschema |  32 ++-
>>   ovn-ic-sb.xml       |  56 +++++
>>   tests/ovn-ic.at     | 404 +++++++++++++++++++++++++++++++++++
>>   tests/ovn-northd.at | 105 +++++----
>>   5 files changed, 1058 insertions(+), 42 deletions(-)
>>
>> diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
>> index ac245a8ed..cfdbd4b40 100644
>> --- a/ic/ovn-ic.c
>> +++ b/ic/ovn-ic.c
> [...]
>
>> +static void
>> +create_pushed_svcs_mon(struct ic_context *ctx,
>> +                       struct hmap *pushed_svcs_map)
>> +{
>> +    struct sbrec_service_monitor *key =
>> +        sbrec_service_monitor_index_init_row(
>> +            ctx->sbrec_service_monitor_by_local_type);
>> +
>> +    sbrec_service_monitor_index_set_local(key, false);
>> +
>> +    const struct sbrec_service_monitor *sb_rec;
>> +    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,
>> +        ctx->sbrec_service_monitor_by_local_type) {
>> +        const char *target_az_name = smap_get_def(&sb_rec->options,
>> +                                                  "az-name", "");
>> +        if (!target_az_name) {
>> +            continue;
>> +        }
> smap_get_def() never returns NULL and, as far as I can tell, the actual
> goal here is to really skip SB.service_monitor records that don't have
> az-name set.  That doesn't happen with this code, we'd just create a
> "pushed_svc" with target_az_name = "".
>
> Do we need to change this to something like below?
>
> const char *target_az_name = smap_get(&sb_rec->options, "az-name");
>
> if (!target_az_name) {
>      continue;
> }
>
> If so, do you mind posting a follow up patch?  We might also need a test
> for this scenario.
>
>> +        create_service_monitor_info(pushed_svcs_map, sb_rec,
>> +                                    &sb_rec->header_.uuid,
>> +                                    ctx->runned_az->name, target_az_name,
>> +                                    NULL, false);
>> +    }
>> +
>> +    sbrec_service_monitor_index_destroy_row(key);
>> +}
>> +
>> +static void
>> +create_synced_svcs_mon(struct ic_context *ctx,
>> +                       struct hmap *synced_svcs_map)
>> +{
>> +    struct icsbrec_service_monitor *key =
>> +        icsbrec_service_monitor_index_init_row(
>> +          ctx->icsbrec_service_monitor_by_target_az);
>> +
>> +    icsbrec_service_monitor_index_set_target_availability_zone(
>> +        key, ctx->runned_az->name);
>> +
>> +    const struct icsbrec_service_monitor *ic_rec;
>> +    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,
>> +        ctx->icsbrec_service_monitor_by_target_az) {
>> +
>> +        const struct sbrec_port_binding *pb =
>> +            find_sb_pb_by_name(ctx->sbrec_port_binding_by_name,
>> +                               ic_rec->logical_port);
>> +
>> +        if (!pb || !pb->up) {
>> +            continue;
>> +        }
>> +
>> +        const char *chassis_name = pb->chassis ? pb->chassis->name : NULL;
>> +        create_service_monitor_info(synced_svcs_map, ic_rec,
>> +                                    &ic_rec->header_.uuid,
>> +                                    ctx->runned_az->name,
>> +                                    NULL, chassis_name, true);
>> +    }
>> +
>> +    icsbrec_service_monitor_index_destroy_row(key);
>> +}
>> +
>> +static void
>> +create_local_ic_svcs_map(struct ic_context *ctx,
>> +                         struct hmap *owned_svc_map)
>> +{
>> +    struct icsbrec_service_monitor *key =
>> +        icsbrec_service_monitor_index_init_row(
>> +          ctx->icsbrec_service_monitor_by_source_az);
>> +
>> +    icsbrec_service_monitor_index_set_source_availability_zone(
>> +        key, ctx->runned_az->name);
>> +
>> +    const struct icsbrec_service_monitor *ic_rec;
>> +    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,
>> +        ctx->icsbrec_service_monitor_by_source_az) {
>> +        create_service_monitor_info(owned_svc_map, ic_rec,
>> +                                    &ic_rec->header_.uuid,
>> +                                    ctx->runned_az->name, NULL,
>> +                                    NULL, true);
>> +    }
>> +
>> +    icsbrec_service_monitor_index_destroy_row(key);
>> +}
>> +
>> +static void
>> +create_local_sb_svcs_map(struct ic_context *ctx,
>> +                         struct hmap *owned_svc_map)
>> +{
>> +    struct sbrec_service_monitor *key =
>> +        sbrec_service_monitor_index_init_row(
>> +          ctx->sbrec_service_monitor_by_ic_learned);
>> +
>> +    sbrec_service_monitor_index_set_ic_learned(
>> +        key, true);
>> +
>> +    const struct sbrec_service_monitor *sb_rec;
>> +    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,
>> +        ctx->sbrec_service_monitor_by_ic_learned) {
>> +        create_service_monitor_info(owned_svc_map, sb_rec,
>> +                                    &sb_rec->header_.uuid,
>> +                                    ctx->runned_az->name, NULL,
>> +                                    NULL, false);
>> +    }
>> +
>> +    sbrec_service_monitor_index_destroy_row(key);
>> +}
>> +
>> +static const struct sbrec_service_monitor *
>> +lookup_sb_svc_rec(struct ic_context *ctx,
>> +                  const struct service_monitor_info *svc_mon)
>> +{
>> +    const struct icsbrec_service_monitor *db_rec =
>> +        svc_mon->db_rec.ic_rec;
>> +    struct sbrec_service_monitor *key =
>> +        sbrec_service_monitor_index_init_row(
>> +            ctx->sbrec_service_monitor_by_local_type_logical_port);
>> +
>> +    sbrec_service_monitor_index_set_local(key, true);
>> +    sbrec_service_monitor_index_set_logical_port(key, db_rec->logical_port);
>> +
>> +    const struct sbrec_service_monitor *sb_rec;
>> +    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sb_rec, key,
>> +        ctx->sbrec_service_monitor_by_local_type_logical_port) {
>> +        if (db_rec->port == sb_rec->port &&
>> +            !strcmp(db_rec->ip, sb_rec->ip) &&
>> +            !strcmp(db_rec->src_ip, sb_rec->src_ip) &&
>> +            !strcmp(db_rec->protocol, sb_rec->protocol)) {
>> +            sbrec_service_monitor_index_destroy_row(key);
>> +            return sb_rec;
>> +        }
>> +    }
>> +
>> +    sbrec_service_monitor_index_destroy_row(key);
>> +
>> +    return NULL;
>> +}
>> +
>> +static const struct icsbrec_service_monitor *
>> +lookup_icsb_svc_rec(struct ic_context *ctx,
>> +                    const struct service_monitor_info *svc_mon)
>> +{
>> +    const struct sbrec_service_monitor *db_rec =
>> +       svc_mon->db_rec.sb_rec;
>> +    struct icsbrec_service_monitor *key =
>> +        icsbrec_service_monitor_index_init_row(
>> +        ctx->icsbrec_service_monitor_by_target_az_logical_port);
>> +
>> +    ovs_assert(svc_mon->dst_az_name);
>> +    icsbrec_service_monitor_index_set_target_availability_zone(
>> +        key, svc_mon->dst_az_name);
>> +
>> +    icsbrec_service_monitor_index_set_logical_port(
>> +        key, db_rec->logical_port);
>> +
>> +    const struct icsbrec_service_monitor *ic_rec;
>> +    ICSBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (ic_rec, key,
>> +        ctx->icsbrec_service_monitor_by_target_az_logical_port) {
>> +        if (db_rec->port == ic_rec->port &&
>> +            !strcmp(db_rec->ip, ic_rec->ip) &&
>> +            !strcmp(db_rec->src_ip, ic_rec->src_ip) &&
>> +            !strcmp(db_rec->protocol, ic_rec->protocol) &&
>> +            !strcmp(db_rec->logical_port, ic_rec->logical_port)) {
>> +            icsbrec_service_monitor_index_destroy_row(key);
>> +            return ic_rec;
>> +        }
>> +    }
>> +
>> +    icsbrec_service_monitor_index_destroy_row(key);
>> +
>> +    return NULL;
>> +}
>> +
>> +static void
>> +create_service_monitor_data(struct ic_context *ctx,
>> +                            struct sync_service_monitor_data *sync_data)
>> +{
>> +    const struct sbrec_sb_global *ic_sb = sbrec_sb_global_first(
>> +                                                ctx->ovnsb_idl);
>> +    const char *svc_monitor_mac = smap_get_def(&ic_sb->options,
>> +        "svc_monitor_mac", "");
>> +
> Here too, smap_get_def() can never return NULL.
>
>> +    if (svc_monitor_mac) {
>> +        sync_data->prpg_svc_monitor_mac = xstrdup(svc_monitor_mac);
> So, if SB.Options:svc_monitor_mac is not present
> sync_data->prpg_svc_monitor_mac will be "".
>
> I know in practice this should be at most transient (because ovn-northd
> will probably reconcile the SB.Options:svc_monitor_mac to an actual MAC
> address value) but should we just return early here if the mac is not
> currently set?
>
> Or do we need to something else?
>
>> +    }
>> +
>> +    create_pushed_svcs_mon(ctx, &sync_data->pushed_svcs_map);
>> +    create_synced_svcs_mon(ctx, &sync_data->synced_svcs_map);
>> +    create_local_ic_svcs_map(ctx, &sync_data->local_ic_svcs_map);
>> +    create_local_sb_svcs_map(ctx, &sync_data->local_sb_svcs_map);
>> +}
>> +
> Regards,
> Dumitru
>

-- 
regards,
Alexandra.

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

Reply via email to