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));