This commit enhances load balancer service monitoring to properly handle
IC-learned (Interconnect-learned) service monitors alongside local monitors.
Key changes include:

1. Added support for tracking IC-learned service monitors separately from
   local monitors while maintaining consistent lookup behavior.
2. Modified service monitor lookup functions to check both local and IC-learned
   monitor maps.
3. Updated LB logical flow building to consider both monitor sources.
4. Added indexing for service monitors by learned type.
5. Extended data structures to pass IC-learned monitors through
   processing.

Signed-off-by: Alexandra Rukomoinikova <arukomoinikova@k2.cloud>
---
 northd/en-lflow.c |   4 ++
 northd/northd.c   | 152 +++++++++++++++++++++++++++++++---------------
 2 files changed, 107 insertions(+), 49 deletions(-)

diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index 63565ef80..2c2715d5d 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -62,6 +62,8 @@ lflow_get_input_data(struct engine_node *node,
         engine_get_input_data("ls_stateful", node);
     struct multicast_igmp_data *multicat_igmp_data =
         engine_get_input_data("multicast_igmp", node);
+    struct ic_learned_svcs_data *ic_learned_svcs_data =
+        engine_get_input_data("ic_learned_svcs", node);
 
     lflow_input->sbrec_logical_flow_table =
         EN_OVSDB_GET(engine_get_input("SB_logical_flow", node));
@@ -91,6 +93,8 @@ lflow_get_input_data(struct engine_node *node,
     lflow_input->route_policies = &route_policies_data->route_policies;
     lflow_input->igmp_groups = &multicat_igmp_data->igmp_groups;
     lflow_input->igmp_lflow_ref = multicat_igmp_data->lflow_ref;
+    lflow_input->ic_learned_svcs = &ic_learned_svcs_data->ic_learned_svs;
+    lflow_input->ic_leared_svcs_lflow_ref = ic_learned_svcs_data->lflow_ref;
 
     struct ed_type_global_config *global_config =
         engine_get_input_data("global_config", node);
diff --git a/northd/northd.c b/northd/northd.c
index 3c29a4da9..b0d43511c 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3689,9 +3689,20 @@ struct service_monitor_info {
     bool required;
 };
 
+static bool
+monitor_info_matches(const struct service_monitor_info *mon_info,
+                     const char *ip, const char *logical_port,
+                     uint16_t service_port, const char *protocol)
+{
+    return (mon_info->sbrec_mon->port == service_port &&
+            !strcmp(mon_info->sbrec_mon->ip, ip) &&
+            !strcmp(mon_info->sbrec_mon->protocol, protocol) &&
+            !strcmp(mon_info->sbrec_mon->logical_port, logical_port));
+}
 
 static struct service_monitor_info *
-get_service_mon(const struct hmap *monitor_map,
+get_service_mon(const struct hmap *local_monitor_map,
+                const struct hmap *ic_learned_monitor_map,
                 const char *ip, const char *logical_port,
                 uint16_t service_port, const char *protocol)
 {
@@ -3700,11 +3711,18 @@ get_service_mon(const struct hmap *monitor_map,
     hash = hash_string(logical_port, hash);
 
     struct service_monitor_info *mon_info;
-    HMAP_FOR_EACH_WITH_HASH (mon_info, hmap_node, hash, monitor_map) {
-        if (mon_info->sbrec_mon->port == service_port &&
-            !strcmp(mon_info->sbrec_mon->ip, ip) &&
-            !strcmp(mon_info->sbrec_mon->protocol, protocol) &&
-            !strcmp(mon_info->sbrec_mon->logical_port, logical_port)) {
+    HMAP_FOR_EACH_WITH_HASH (mon_info, hmap_node, hash,
+        local_monitor_map) {
+        if (monitor_info_matches(mon_info, ip, logical_port,
+                                 service_port, protocol)) {
+            return mon_info;
+        }
+    }
+
+    HMAP_FOR_EACH_WITH_HASH (mon_info, hmap_node, hash,
+        ic_learned_monitor_map) {
+        if (monitor_info_matches(mon_info, ip, logical_port,
+                                 service_port, protocol)) {
             return mon_info;
         }
     }
@@ -3714,14 +3732,15 @@ get_service_mon(const struct hmap *monitor_map,
 
 static struct service_monitor_info *
 create_or_get_service_mon(struct ovsdb_idl_txn *ovnsb_txn,
-                          struct hmap *monitor_map,
+                          struct hmap *local_monitor_map,
+                          struct hmap *ic_learned_monitor_map,
                           const char *ip, const char *logical_port,
                           uint16_t service_port, const char *protocol,
                           const char *chassis_name)
 {
     struct service_monitor_info *mon_info =
-        get_service_mon(monitor_map, ip, logical_port, service_port,
-                        protocol);
+        get_service_mon(local_monitor_map, ic_learned_monitor_map,
+                        ip, logical_port, service_port, protocol);
 
     if (mon_info) {
         if (chassis_name && strcmp(mon_info->sbrec_mon->chassis_name,
@@ -3748,7 +3767,7 @@ create_or_get_service_mon(struct ovsdb_idl_txn *ovnsb_txn,
     }
     mon_info = xzalloc(sizeof *mon_info);
     mon_info->sbrec_mon = sbrec_mon;
-    hmap_insert(monitor_map, &mon_info->hmap_node, hash);
+    hmap_insert(local_monitor_map, &mon_info->hmap_node, hash);
     return mon_info;
 }
 
@@ -3757,7 +3776,9 @@ ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn,
                   const struct ovn_northd_lb *lb,
                   const char *svc_monitor_mac,
                   const struct eth_addr *svc_monitor_mac_ea,
-                  struct hmap *monitor_map, struct hmap *ls_ports,
+                  struct hmap *local_monitor_map,
+                  struct hmap *ic_learned_monitor_map,
+                  struct hmap *ls_ports,
                   struct sset *svc_monitor_lsps)
 {
     if (lb->template) {
@@ -3797,7 +3818,9 @@ ovn_lb_svc_create(struct ovsdb_idl_txn *ovnsb_txn,
             }
 
             struct service_monitor_info *mon_info =
-                create_or_get_service_mon(ovnsb_txn, monitor_map,
+                create_or_get_service_mon(ovnsb_txn,
+                                          local_monitor_map,
+                                          ic_learned_monitor_map,
                                           backend->ip_str,
                                           backend_nb->logical_port,
                                           backend->port,
@@ -3842,7 +3865,8 @@ build_lb_vip_actions(const struct ovn_northd_lb *lb,
                      struct ds *skip_snat_action,
                      struct ds *force_snat_action,
                      bool ls_dp,
-                     const struct hmap *svc_monitor_map)
+                     const struct hmap *local_monitor_map,
+                     const struct hmap *ic_learned_monitor_map)
 {
     bool reject =
         vector_is_empty(&lb_vip->backends) && lb_vip->empty_backend_rej;
@@ -3879,7 +3903,8 @@ build_lb_vip_actions(const struct ovn_northd_lb *lb,
             }
 
             struct service_monitor_info *mon_info = get_service_mon(
-                svc_monitor_map, backend->ip_str, backend_nb->logical_port,
+                local_monitor_map, ic_learned_monitor_map,
+                backend->ip_str, backend_nb->logical_port,
                 backend->port, protocol);
 
             if (!mon_info) {
@@ -4038,16 +4063,23 @@ build_lb_datapaths(const struct hmap *lbs, const struct 
hmap *lb_groups,
 static void
 build_lb_svcs(
     struct ovsdb_idl_txn *ovnsb_txn,
-    const struct sbrec_service_monitor_table *sbrec_service_monitor_table,
+    struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type,
     const char *svc_monitor_mac,
     const struct eth_addr *svc_monitor_mac_ea,
     struct hmap *ls_ports, struct hmap *lb_dps_map,
     struct sset *svc_monitor_lsps,
-    struct hmap *svc_monitor_map)
+    struct hmap *svc_monitor_map,
+    struct hmap *ic_learned_svs)
 {
     const struct sbrec_service_monitor *sbrec_mon;
-    SBREC_SERVICE_MONITOR_TABLE_FOR_EACH (sbrec_mon,
-                            sbrec_service_monitor_table) {
+    struct sbrec_service_monitor *key =
+        sbrec_service_monitor_index_init_row(
+            sbrec_service_monitor_by_learned_type);
+
+    sbrec_service_monitor_set_ic_learned(key, false);
+
+    SBREC_SERVICE_MONITOR_FOR_EACH_EQUAL (sbrec_mon, key,
+        sbrec_service_monitor_by_learned_type) {
         uint32_t hash = sbrec_mon->port;
         hash = hash_string(sbrec_mon->ip, hash);
         hash = hash_string(sbrec_mon->logical_port, hash);
@@ -4057,11 +4089,13 @@ build_lb_svcs(
         hmap_insert(svc_monitor_map, &mon_info->hmap_node, hash);
     }
 
+    sbrec_service_monitor_index_destroy_row(key);
+
     struct ovn_lb_datapaths *lb_dps;
     HMAP_FOR_EACH (lb_dps, hmap_node, lb_dps_map) {
         ovn_lb_svc_create(ovnsb_txn, lb_dps->lb, svc_monitor_mac,
-                          svc_monitor_mac_ea, svc_monitor_map, ls_ports,
-                          svc_monitor_lsps);
+                          svc_monitor_mac_ea, svc_monitor_map,
+                          ic_learned_svs, ls_ports, svc_monitor_lsps);
     }
 
     struct service_monitor_info *mon_info;
@@ -4133,17 +4167,19 @@ build_lb_count_dps(struct hmap *lb_dps_map,
 static void
 build_lb_port_related_data(
     struct ovsdb_idl_txn *ovnsb_txn,
-    const struct sbrec_service_monitor_table *sbrec_service_monitor_table,
+    struct ovsdb_idl_index *sbrec_service_monitor_by_learned_type,
     const char *svc_monitor_mac,
     const struct eth_addr *svc_monitor_mac_ea,
     struct ovn_datapaths *lr_datapaths, struct hmap *ls_ports,
     struct hmap *lb_dps_map, struct hmap *lb_group_dps_map,
     struct sset *svc_monitor_lsps,
-    struct hmap *svc_monitor_map)
+    struct hmap *svc_monitor_map,
+    struct hmap *ic_learned_svs)
 {
-    build_lb_svcs(ovnsb_txn, sbrec_service_monitor_table, svc_monitor_mac,
-                  svc_monitor_mac_ea, ls_ports, lb_dps_map,
-                  svc_monitor_lsps, svc_monitor_map);
+    build_lb_svcs(ovnsb_txn, sbrec_service_monitor_by_learned_type,
+                  svc_monitor_mac, svc_monitor_mac_ea, ls_ports,
+                  lb_dps_map, svc_monitor_lsps, svc_monitor_map,
+                  ic_learned_svs);
     build_lswitch_lbs_from_lrouter(lr_datapaths, lb_dps_map, lb_group_dps_map);
 }
 
@@ -8601,7 +8637,8 @@ build_lb_rules(struct lflow_table *lflows, struct 
ovn_lb_datapaths *lb_dps,
                const struct ovn_datapaths *ls_datapaths,
                struct ds *match, struct ds *action,
                const struct shash *meter_groups,
-               const struct hmap *svc_monitor_map)
+               const struct hmap *local_monitor_map,
+               const struct hmap *ic_learned_monitor_map)
 {
     const struct ovn_northd_lb *lb = lb_dps->lb;
     for (size_t i = 0; i < lb->n_vips; i++) {
@@ -8618,7 +8655,8 @@ build_lb_rules(struct lflow_table *lflows, struct 
ovn_lb_datapaths *lb_dps,
         bool reject = build_lb_vip_actions(lb, lb_vip, lb_vip_nb, action,
                                            lb->selection_fields,
                                            NULL, NULL, true,
-                                           svc_monitor_map);
+                                           local_monitor_map,
+                                           ic_learned_monitor_map);
 
         ds_put_format(match, "ct.new && %s.dst == %s", ip_match,
                       lb_vip->vip_str);
@@ -12600,7 +12638,8 @@ build_lrouter_nat_flows_for_lb(
     struct lflow_table *lflows,
     struct ds *match, struct ds *action,
     const struct shash *meter_groups,
-    const struct hmap *svc_monitor_map)
+    const struct hmap *local_monitor_map,
+    const struct hmap *ic_learned_monitor_map)
 {
     const struct ovn_northd_lb *lb = lb_dps->lb;
     bool ipv4 = lb_vip->address_family == AF_INET;
@@ -12624,7 +12663,8 @@ build_lrouter_nat_flows_for_lb(
     bool reject = build_lb_vip_actions(lb, lb_vip, vips_nb, action,
                                        lb->selection_fields, &skip_snat_act,
                                        &force_snat_act, false,
-                                       svc_monitor_map);
+                                       local_monitor_map,
+                                       ic_learned_monitor_map);
 
     /* Higher priority rules are added for load-balancing in DNAT
      * table.  For every match (on a VIP[:port]), we add two flows.
@@ -12782,7 +12822,8 @@ build_lswitch_flows_for_lb(struct ovn_lb_datapaths 
*lb_dps,
                            struct lflow_table *lflows,
                            const struct shash *meter_groups,
                            const struct ovn_datapaths *ls_datapaths,
-                           const struct hmap *svc_monitor_map,
+                           const struct hmap *local_svc_monitor_map,
+                           const struct hmap *ic_learned_svc_monitor_map,
                            struct ds *match, struct ds *action)
 {
     if (!lb_dps->n_nb_ls) {
@@ -12826,7 +12867,8 @@ build_lswitch_flows_for_lb(struct ovn_lb_datapaths 
*lb_dps,
      * REGBIT_CONNTRACK_COMMIT. */
     build_lb_rules_pre_stateful(lflows, lb_dps, ls_datapaths, match, action);
     build_lb_rules(lflows, lb_dps, ls_datapaths, match, action,
-                   meter_groups, svc_monitor_map);
+                   meter_groups, local_svc_monitor_map,
+                   ic_learned_svc_monitor_map);
 }
 
 /* If there are any load balancing rules, we should send the packet to
@@ -12898,7 +12940,8 @@ build_lrouter_flows_for_lb(struct ovn_lb_datapaths 
*lb_dps,
                            const struct shash *meter_groups,
                            const struct ovn_datapaths *lr_datapaths,
                            const struct lr_stateful_table *lr_stateful_table,
-                           const struct hmap *svc_monitor_map,
+                           const struct hmap *local_monitor_map,
+                           const struct hmap *ic_learned_monitor_map,
                            struct ds *match, struct ds *action)
 {
     size_t index;
@@ -12914,7 +12957,8 @@ build_lrouter_flows_for_lb(struct ovn_lb_datapaths 
*lb_dps,
         build_lrouter_nat_flows_for_lb(lb_vip, lb_dps, &lb->vips_nb[i],
                                        lr_datapaths, lr_stateful_table, lflows,
                                        match, action, meter_groups,
-                                       svc_monitor_map);
+                                       local_monitor_map,
+                                       ic_learned_monitor_map);
 
         build_lrouter_allow_vip_traffic_template(lflows, lb_dps, lb_vip, lb,
                                                  lr_datapaths);
@@ -17998,7 +18042,8 @@ struct lswitch_flow_build_info {
     struct lflow_table *lflows;
     const struct shash *meter_groups;
     const struct hmap *lb_dps_map;
-    const struct hmap *svc_monitor_map;
+    const struct hmap *local_svc_monitor_map;
+    const struct hmap *ic_learned_svc_monitor_map;
     const struct sset *bfd_ports;
     const struct chassis_features *features;
     char *svc_check_match;
@@ -18275,12 +18320,14 @@ build_lflows_thread(void *arg)
                                                lsi->meter_groups,
                                                lsi->lr_datapaths,
                                                lsi->lr_stateful_table,
-                                               lsi->svc_monitor_map,
+                                               lsi->local_svc_monitor_map,
+                                               lsi->ic_learned_svc_monitor_map,
                                                &lsi->match, &lsi->actions);
                     build_lswitch_flows_for_lb(lb_dps, lsi->lflows,
                                                lsi->meter_groups,
                                                lsi->ls_datapaths,
-                                               lsi->svc_monitor_map,
+                                               lsi->local_svc_monitor_map,
+                                               lsi->ic_learned_svc_monitor_map,
                                                &lsi->match, &lsi->actions);
                 }
             }
@@ -18374,7 +18421,8 @@ build_lswitch_and_lrouter_flows(
     struct lflow_table *lflows,
     const struct shash *meter_groups,
     const struct hmap *lb_dps_map,
-    const struct hmap *svc_monitor_map,
+    const struct hmap *local_svc_monitor_map,
+    const struct hmap *ic_learned_svc_monitor_map,
     const struct sset *bfd_ports,
     const struct chassis_features *features,
     const char *svc_monitor_mac,
@@ -18409,7 +18457,10 @@ build_lswitch_and_lrouter_flows(
             lsiv[index].ls_stateful_table = ls_stateful_table;
             lsiv[index].meter_groups = meter_groups;
             lsiv[index].lb_dps_map = lb_dps_map;
-            lsiv[index].svc_monitor_map = svc_monitor_map;
+            lsiv[index].local_svc_monitor_map =
+                local_svc_monitor_map;
+            lsiv[index].ic_learned_svc_monitor_map =
+                ic_learned_svc_monitor_map;
             lsiv[index].bfd_ports = bfd_ports;
             lsiv[index].features = features;
             lsiv[index].svc_check_match = svc_check_match;
@@ -18453,7 +18504,8 @@ build_lswitch_and_lrouter_flows(
             .lflows = lflows,
             .meter_groups = meter_groups,
             .lb_dps_map = lb_dps_map,
-            .svc_monitor_map = svc_monitor_map,
+            .local_svc_monitor_map = local_svc_monitor_map,
+            .ic_learned_svc_monitor_map = ic_learned_svc_monitor_map,
             .bfd_ports = bfd_ports,
             .features = features,
             .svc_check_match = svc_check_match,
@@ -18510,11 +18562,13 @@ build_lswitch_and_lrouter_flows(
                                               lsi.lr_datapaths, &lsi.match);
             build_lrouter_flows_for_lb(lb_dps, lsi.lflows, lsi.meter_groups,
                                        lsi.lr_datapaths, lsi.lr_stateful_table,
-                                       lsi.svc_monitor_map,
+                                       lsi.local_svc_monitor_map,
+                                       lsi.ic_learned_svc_monitor_map,
                                        &lsi.match, &lsi.actions);
             build_lswitch_flows_for_lb(lb_dps, lsi.lflows, lsi.meter_groups,
                                        lsi.ls_datapaths,
-                                       lsi.svc_monitor_map,
+                                       lsi.local_svc_monitor_map,
+                                       lsi.ic_learned_svc_monitor_map,
                                        &lsi.match, &lsi.actions);
         }
         stopwatch_stop(LFLOWS_LBS_STOPWATCH_NAME, time_msec());
@@ -18623,6 +18677,7 @@ void build_lflows(struct ovsdb_idl_txn *ovnsb_txn,
                                     input_data->meter_groups,
                                     input_data->lb_datapaths_map,
                                     input_data->svc_monitor_map,
+                                    input_data->ic_learned_svcs,
                                     input_data->bfd_ports,
                                     input_data->features,
                                     input_data->svc_monitor_mac,
@@ -18879,11 +18934,13 @@ lflow_handle_northd_lb_changes(struct ovsdb_idl_txn 
*ovnsb_txn,
                                    lflow_input->lr_datapaths,
                                    lflow_input->lr_stateful_table,
                                    lflow_input->svc_monitor_map,
+                                   lflow_input->ic_learned_svcs,
                                    &match, &actions);
         build_lswitch_flows_for_lb(lb_dps, lflows,
                                    lflow_input->meter_groups,
                                    lflow_input->ls_datapaths,
                                    lflow_input->svc_monitor_map,
+                                   lflow_input->ic_learned_svcs,
                                    &match, &actions);
 
         ds_destroy(&match);
@@ -19612,14 +19669,11 @@ ovnnb_db_run(struct northd_input *input_data,
                 &data->ls_datapaths.datapaths, &data->lr_datapaths.datapaths,
                 &data->ls_ports, &data->lr_ports);
     build_lb_port_related_data(ovnsb_txn,
-                               input_data->sbrec_service_monitor_table,
-                               input_data->svc_monitor_mac,
-                               &input_data->svc_monitor_mac_ea,
-                               &data->lr_datapaths, &data->ls_ports,
-                               &data->lb_datapaths_map,
-                               &data->lb_group_datapaths_map,
-                               &data->svc_monitor_lsps,
-                               &data->svc_monitor_map);
+        input_data->sbrec_service_monitor_by_learned_type,
+        input_data->svc_monitor_mac, &input_data->svc_monitor_mac_ea,
+        &data->lr_datapaths, &data->ls_ports, &data->lb_datapaths_map,
+        &data->lb_group_datapaths_map, &data->svc_monitor_lsps,
+        &data->svc_monitor_map, input_data->ic_learned_svs);
     build_lb_count_dps(&data->lb_datapaths_map,
                        ods_size(&data->ls_datapaths),
                        ods_size(&data->lr_datapaths));
-- 
2.48.1

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

Reply via email to