On 2/17/26 6:58 PM, Alexandra Rukomoinikova wrote:
> Propagate health status from SB Service_Monitor to NB
> Logical_Switch_Port_Health_Check table.
> 
> This synchronization enables CMS (Cloud Management System) to make
> informed decisions about virtual machine availability, routing, and
> failover based on the current health status of monitored service
> 
> Signed-off-by: Alexandra Rukomoinikova <[email protected]>
> ---
> v2 --> v3: fixed Dumitru's comments
> ---

Hi Alexandra,

>  northd/en-sync-from-sb.c         |  6 +++
>  northd/inc-proc-northd.c         |  8 ++++
>  northd/northd.c                  | 82 ++++++++++++++++++++++++++++++++
>  northd/northd.h                  |  1 +
>  ovn-nb.ovsschema                 |  8 +++-
>  ovn-nb.xml                       |  8 ++++
>  tests/ovn-inc-proc-graph-dump.at |  1 +
>  tests/system-ovn.at              |  6 +++
>  8 files changed, 118 insertions(+), 2 deletions(-)
> 
> diff --git a/northd/en-sync-from-sb.c b/northd/en-sync-from-sb.c
> index de822115d..bb61638a5 100644
> --- a/northd/en-sync-from-sb.c
> +++ b/northd/en-sync-from-sb.c
> @@ -50,8 +50,14 @@ en_sync_from_sb_run(struct engine_node *node, void *data 
> OVS_UNUSED)
>          EN_OVSDB_GET(engine_get_input("SB_port_binding", node));
>      const struct sbrec_ha_chassis_group_table *sb_ha_ch_grp_table =
>          EN_OVSDB_GET(engine_get_input("SB_ha_chassis_group", node));
> +    struct ovsdb_idl_index *sbrec_service_monitor_by_service_type =
> +        engine_ovsdb_node_get_index(
> +            engine_get_input("SB_service_monitor", node),
> +            "sbrec_service_monitor_by_service_type");
> +
>      ovnsb_db_run(eng_ctx->ovnsb_idl_txn,
>                   sb_pb_table, sb_ha_ch_grp_table,
> +                 sbrec_service_monitor_by_service_type,
>                   &nd->ls_ports, &nd->lr_ports);
>  
>      return EN_UNCHANGED;
> diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
> index 732066638..b79272324 100644
> --- a/northd/inc-proc-northd.c
> +++ b/northd/inc-proc-northd.c
> @@ -477,6 +477,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
>      engine_add_input(&en_sync_from_sb, &en_northd,
>                       sync_from_sb_northd_handler);
>      engine_add_input(&en_sync_from_sb, &en_sb_port_binding, NULL);
> +    engine_add_input(&en_sync_from_sb, &en_sb_service_monitor, NULL);
>      engine_add_input(&en_sync_from_sb, &en_sb_ha_chassis_group, NULL);
>  
>      engine_add_input(&en_northd_output, &en_acl_id, NULL);
> @@ -593,6 +594,13 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
>                                  "sbrec_service_monitor_by_learned_type",
>                                  sbrec_service_monitor_by_learned_type);
>  
> +    struct ovsdb_idl_index *sbrec_service_monitor_by_service_type
> +        = ovsdb_idl_index_create1(sb->idl,
> +                                  &sbrec_service_monitor_col_type);
> +    engine_ovsdb_node_add_index(&en_sb_service_monitor,
> +                                "sbrec_service_monitor_by_service_type",
> +                                sbrec_service_monitor_by_service_type);
> +
>      struct ed_type_global_config *global_config =
>          engine_get_internal_data(&en_global_config);
>      unixctl_command_register("debug/chassis-features-list", "", 0, 0,
> diff --git a/northd/northd.c b/northd/northd.c
> index 90d8edfe9..98f97af26 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -21245,11 +21245,91 @@ handle_port_binding_changes(const struct 
> sbrec_port_binding_table *sb_pb_table,
>      hmapx_destroy(&lr_groups);
>  }
>  
> +static bool
> +svc_monitor_matches_health_check(const struct sbrec_service_monitor 
> *sbrec_mon,
> +                                 const char *protocol,
> +                                 const char *src_ip,
> +                                 const char *target_ip,
> +                                 uint16_t destination_port)
> +{
> +    if (strcmp(sbrec_mon->protocol, protocol) != 0) {
> +        return false;
> +    }
> +
> +    if (!strcmp(protocol, "tcp") || !strcmp(protocol, "udp")) {
> +        if (sbrec_mon->port != destination_port) {
> +            return false;
> +        }
> +    }
> +
> +    if (!strcmp(sbrec_mon->src_ip, src_ip)) {
> +        return true;
> +    }
> +
> +    if (!strcmp(sbrec_mon->ip, target_ip)) {
> +        return true;
> +    }
> +
> +    return false;

As discussed on the other thread this should be:

+    if (strcmp(sbrec_mon->src_ip, src_ip)) {
+        return false;
+    }
+
+    if (strcmp(sbrec_mon->ip, target_ip)) {
+        return false;
+    }
+
+    return true;

> +}
> +
> +static void
> +handle_service_monitor_changes(
> +    struct ovsdb_idl_index *sbrec_service_monitor_by_service_type,
> +    const struct hmap *ls_ports)
> +{
> +    const struct sbrec_service_monitor *sbrec_mon;
> +    struct sbrec_service_monitor *key =
> +        sbrec_service_monitor_index_init_row(
> +            sbrec_service_monitor_by_service_type);
> +
> +    sbrec_service_monitor_set_type(key, "logical-switch-port");
> +
> +    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sbrec_mon, key,
> +            sbrec_service_monitor_by_service_type) {
> +
> +        struct ovn_port *op = ovn_port_find(ls_ports,
> +                                            sbrec_mon->logical_port);
> +        if (!op) {
> +            continue;
> +        }
> +
> +        ovs_assert(op->nbsp && op->nbsp->n_health_checks);
> +
> +        /* There shouldn't be many health checks on port,
> +         * liniar check shouldn't be heavy. */

Typo: liniar should be linear.

I fixed this and the "matches" function up and applied the patch to main.

Regards,
Dumitru

> +        for (size_t i = 0; i < op->nbsp->n_health_checks; i++) {
> +            const struct nbrec_logical_switch_port_health_check *lsp_hc =
> +                op->nbsp->health_checks[i];
> +
> +            if (!svc_monitor_matches_health_check(sbrec_mon,
> +                                                  lsp_hc->protocol,
> +                                                  lsp_hc->src_ip,
> +                                                  lsp_hc->address,
> +                                                  lsp_hc->port)) {
> +                continue;
> +            }
> +
> +            const char *desired_status = sbrec_mon->status;
> +            if (desired_status) {
> +                if (!lsp_hc->status ||
> +                    strcmp(lsp_hc->status, desired_status)) {
> +                    nbrec_logical_switch_port_health_check_set_status(
> +                        lsp_hc, sbrec_mon->status);
> +                }
> +            }
> +        }
> +    }
> +
> +    sbrec_service_monitor_index_destroy_row(key);
> +}
> +
>  /* Handle a fairly small set of changes in the southbound database. */
>  void
>  ovnsb_db_run(struct ovsdb_idl_txn *ovnsb_txn,
>               const struct sbrec_port_binding_table *sb_pb_table,
>               const struct sbrec_ha_chassis_group_table *sb_ha_ch_grp_table,
> +             struct ovsdb_idl_index *sbrec_service_monitor_by_service_type,
>               struct hmap *ls_ports,
>               struct hmap *lr_ports)
>  {
> @@ -21260,6 +21340,8 @@ ovnsb_db_run(struct ovsdb_idl_txn *ovnsb_txn,
>      struct shash ha_ref_chassis_map = SHASH_INITIALIZER(&ha_ref_chassis_map);
>      handle_port_binding_changes(sb_pb_table, sb_ha_ch_grp_table,
>                                  ls_ports, lr_ports, &ha_ref_chassis_map);
> +    handle_service_monitor_changes(sbrec_service_monitor_by_service_type,
> +                                   ls_ports);
>      update_sb_ha_group_ref_chassis(sb_ha_ch_grp_table, &ha_ref_chassis_map);
>  
>      shash_destroy(&ha_ref_chassis_map);
> diff --git a/northd/northd.h b/northd/northd.h
> index c2571fb30..cc05c3b1f 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -905,6 +905,7 @@ void ovnnb_db_run(struct northd_input *input_data,
>  void ovnsb_db_run(struct ovsdb_idl_txn *ovnsb_txn,
>                    const struct sbrec_port_binding_table *,
>                    const struct sbrec_ha_chassis_group_table *,
> +                  struct ovsdb_idl_index *,
>                    struct hmap *ls_ports,
>                    struct hmap *lr_ports);
>  bool northd_handle_ls_changes(struct ovsdb_idl_txn *,
> diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema
> index fea4cd130..07ad1f467 100644
> --- a/ovn-nb.ovsschema
> +++ b/ovn-nb.ovsschema
> @@ -1,7 +1,7 @@
>  {
>      "name": "OVN_Northbound",
> -    "version": "7.17.0",
> -    "cksum": "2579043495 45129",
> +    "version": "7.18.0",
> +    "cksum": "3798579343 45342",
>      "tables": {
>          "NB_Global": {
>              "columns": {
> @@ -268,6 +268,10 @@
>                  "address": {"type": {"key": "string",
>                                       "min": 0,
>                                       "max": 1}},
> +                "status": {
> +                    "type": {"key": {"type": "string",
> +                             "enum": ["set", ["online", "offline", 
> "error"]]},
> +                             "min": 0, "max": 1}},
>                  "options": {
>                       "type": {"key": "string",
>                                "value": "string",
> diff --git a/ovn-nb.xml b/ovn-nb.xml
> index 627394cc4..eb52f8c7c 100644
> --- a/ovn-nb.xml
> +++ b/ovn-nb.xml
> @@ -2280,6 +2280,14 @@
>        IP address to monitor for the health check.
>      </column>
>  
> +    <column name="status">
> +      Health status synchronized from the <code>status</code> field of
> +      corresponding service monitor in the SBDB. This status indicates
> +      the current availability of logical switch port for the CMS to
> +      determine service virtual machine health and make routing or
> +      failover decisions.
> +    </column>
> +
>      <column name="options" key="interval" type='{"type": "integer"}'>
>        The interval, in seconds, between service monitor checks.
>      </column>
> diff --git a/tests/ovn-inc-proc-graph-dump.at 
> b/tests/ovn-inc-proc-graph-dump.at
> index ff2c8c0c7..a31aad6e7 100644
> --- a/tests/ovn-inc-proc-graph-dump.at
> +++ b/tests/ovn-inc-proc-graph-dump.at
> @@ -98,6 +98,7 @@ digraph "Incremental-Processing-Engine" {
>       sync_from_sb [[style=filled, shape=box, fillcolor=white, 
> label="sync_from_sb"]];
>       northd -> sync_from_sb [[label="sync_from_sb_northd_handler"]];
>       SB_port_binding -> sync_from_sb [[label=""]];
> +     SB_service_monitor -> sync_from_sb [[label=""]];
>       SB_ha_chassis_group -> sync_from_sb [[label=""]];
>       lr_nat [[style=filled, shape=box, fillcolor=white, label="lr_nat"]];
>       northd -> lr_nat [[label="lr_nat_northd_handler"]];
> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> index b88455dea..d90843220 100644
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -21037,6 +21037,7 @@ check_row_count sb:Service_Monitor 1
>  
>  # Wait until the services are set to online.
>  wait_row_count Service_Monitor 1 status=online
> +wait_row_count nb:Logical_Switch_Port_Health_Check 1 status=online 
> protocol=icmp
>  
>  check ovn-nbctl lsp-hc-add lport tcp 192.168.0.250 4041 192.168.0.10
>  
> @@ -21047,6 +21048,7 @@ NETNS_DAEMONIZE([lport], [nc -l -k 192.168.0.10 
> 4041], [lport_tcp.pid])
>  
>  # Wait until the services are set to online.
>  wait_row_count Service_Monitor 2 status=online
> +wait_row_count nb:Logical_Switch_Port_Health_Check 1 status=online 
> protocol=tcp
>  
>  check ovn-nbctl lsp-hc-add lport udp 192.168.0.250 4042 192.168.0.10
>  
> @@ -21054,6 +21056,7 @@ NETNS_DAEMONIZE([lport], [nc -ulp 4042], 
> [lport_udp.pid])
>  
>  # Wait until the services are set to online.
>  wait_row_count Service_Monitor 3 status=online
> +wait_row_count nb:Logical_Switch_Port_Health_Check 1 status=online 
> protocol=udp
>  
>  check ovn-nbctl lsp-hc-del lport
>  
> @@ -21063,6 +21066,7 @@ check_row_count sb:Service_Monitor 1
>  
>  # Wait until the services are set to online.
>  wait_row_count Service_Monitor 1 status=online
> +wait_row_count nb:Logical_Switch_Port_Health_Check 1 status=online 
> protocol=icmp
>  
>  # IPv6 TCP health check
>  check ovn-nbctl lsp-hc-add lport tcp 2001:db8::ff 4043 2001:db8::10
> @@ -21074,6 +21078,7 @@ NETNS_DAEMONIZE([lport], [nc -6 -l -k 2001:db8::10 
> 4043], [lport_ipv6_tcp.pid])
>  
>  # Wait until the services are set to online.
>  wait_row_count Service_Monitor 2 status=online
> +wait_row_count nb:Logical_Switch_Port_Health_Check 1 status=online 
> protocol=tcp
>  
>  # IPv6 UDP health check
>  check ovn-nbctl lsp-hc-add lport udp 2001:db8::ff 4044 2001:db8::10
> @@ -21084,6 +21089,7 @@ NETNS_DAEMONIZE([lport], [nc -6 -u -l 2001:db8::10 
> 4044], [lport_ipv6_udp.pid])
>  
>  # Wait until the services are set to online.
>  wait_row_count Service_Monitor 3 status=online
> +wait_row_count nb:Logical_Switch_Port_Health_Check 1 status=online 
> protocol=udp
>  
>  OVN_CLEANUP_CONTROLLER([hv1])
>  


_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to