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 <[email protected]> --- v1 --> v2: renamed the data structures related to svc_monitor_map to local_*, so that there is a clear separation between local and learned structures throughout the code --- northd/en-lflow.c | 6 ++ northd/northd.c | 208 ++++++++++++++++++++++++++++++++-------------- northd/northd.h | 6 ++ 3 files changed, 156 insertions(+), 64 deletions(-) diff --git a/northd/en-lflow.c b/northd/en-lflow.c index e46bba7b9..08427b52f 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_svc_monitors_data *ic_learned_svc_monitors_data = + engine_get_input_data("ic_learned_svc_monitors", node); lflow_input->sbrec_logical_flow_table = EN_OVSDB_GET(engine_get_input("SB_logical_flow", node)); @@ -92,6 +94,10 @@ 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_svc_monitors_map = + &ic_learned_svc_monitors_data->ic_learned_svc_monitors_map; + lflow_input->ic_learned_svc_monitors_lflow_ref = + ic_learned_svc_monitors_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 fff68be1e..c36e4a677 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -717,6 +717,18 @@ init_mcast_info_for_datapath(struct ovn_datapath *od) } } +static inline struct svc_monitors_map_data +svc_monitors_map_data_init(const struct hmap *local_svc_monitors_map, + const struct hmap *ic_learned_svc_monitors_map, + struct lflow_ref *ic_learned_svc_monitors_lflow_ref) +{ + return (struct svc_monitors_map_data) { + .local_svc_monitors_map = local_svc_monitors_map, + .ic_learned_svc_monitors_map = ic_learned_svc_monitors_map, + .lflow_ref = ic_learned_svc_monitors_lflow_ref, + }; +} + static void destroy_mcast_info_for_switch_datapath(struct ovn_datapath *od) { @@ -2926,8 +2938,20 @@ struct service_monitor_info { }; +static inline 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_svc_monitors_map, + const struct hmap *ic_learned_svc_monitors_map, const char *ip, const char *logical_port, uint16_t service_port, const char *protocol) { @@ -2936,12 +2960,17 @@ 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)) { - return mon_info; + for (const struct hmap *map = local_svc_monitors_map; ; + map = (map == local_svc_monitors_map) + ? ic_learned_svc_monitors_map : NULL) { + if (!map) { + break; + } + HMAP_FOR_EACH_WITH_HASH (mon_info, hmap_node, hash, map) { + if (monitor_info_matches(mon_info, ip, logical_port, + service_port, protocol)) { + return mon_info; + } } } @@ -2950,14 +2979,16 @@ 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_svc_monitors_map, + struct hmap *ic_learned_svc_monitors_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_svc_monitors_map, + ic_learned_svc_monitors_map, + ip, logical_port, service_port, protocol); if (mon_info) { if (chassis_name && strcmp(mon_info->sbrec_mon->chassis_name, @@ -2979,12 +3010,13 @@ create_or_get_service_mon(struct ovsdb_idl_txn *ovnsb_txn, sbrec_service_monitor_set_port(sbrec_mon, service_port); sbrec_service_monitor_set_logical_port(sbrec_mon, logical_port); sbrec_service_monitor_set_protocol(sbrec_mon, protocol); + sbrec_service_monitor_set_ic_learned(sbrec_mon, false); if (chassis_name) { sbrec_service_monitor_set_chassis_name(sbrec_mon, chassis_name); } mon_info = xzalloc(sizeof *mon_info); mon_info->sbrec_mon = sbrec_mon; - hmap_insert(monitor_map, &mon_info->hmap_node, hash); + hmap_insert(local_svc_monitors_map, &mon_info->hmap_node, hash); return mon_info; } @@ -2993,8 +3025,10 @@ 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 sset *svc_monitor_lsps) + struct hmap *ls_ports, + struct sset *svc_monitor_lsps, + struct hmap *local_svc_monitors_map, + struct hmap *ic_learned_svc_monitors_map) { if (lb->template) { return; @@ -3033,7 +3067,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_svc_monitors_map, + ic_learned_svc_monitors_map, backend->ip_str, backend_nb->logical_port, backend->port, @@ -3077,8 +3113,8 @@ build_lb_vip_actions(const struct ovn_northd_lb *lb, struct ds *action, char *selection_fields, struct ds *skip_snat_action, struct ds *force_snat_action, - bool ls_dp, - const struct hmap *svc_monitor_map) + const struct svc_monitors_map_data *svc_mons_data, + bool ls_dp) { bool reject = vector_is_empty(&lb_vip->backends) && lb_vip->empty_backend_rej; @@ -3114,9 +3150,13 @@ build_lb_vip_actions(const struct ovn_northd_lb *lb, protocol = "tcp"; } - struct service_monitor_info *mon_info = get_service_mon( - svc_monitor_map, backend->ip_str, backend_nb->logical_port, - backend->port, protocol); + struct service_monitor_info *mon_info = + get_service_mon(svc_mons_data->local_svc_monitors_map, + svc_mons_data->ic_learned_svc_monitors_map, + backend->ip_str, + backend_nb->logical_port, + backend->port, + protocol); if (!mon_info) { continue; @@ -3274,37 +3314,51 @@ 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 *local_svc_monitors_map, + struct hmap *ic_learned_svc_monitors_map) { 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); struct service_monitor_info *mon_info = xzalloc(sizeof *mon_info); mon_info->sbrec_mon = sbrec_mon; mon_info->required = false; - hmap_insert(svc_monitor_map, &mon_info->hmap_node, hash); + hmap_insert(local_svc_monitors_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); + ovn_lb_svc_create(ovnsb_txn, lb_dps->lb, + svc_monitor_mac, + svc_monitor_mac_ea, + ls_ports, + svc_monitor_lsps, + local_svc_monitors_map, + ic_learned_svc_monitors_map); } struct service_monitor_info *mon_info; - HMAP_FOR_EACH_SAFE (mon_info, hmap_node, svc_monitor_map) { + HMAP_FOR_EACH_SAFE (mon_info, hmap_node, local_svc_monitors_map) { if (!mon_info->required) { sbrec_service_monitor_delete(mon_info->sbrec_mon); - hmap_remove(svc_monitor_map, &mon_info->hmap_node); + hmap_remove(local_svc_monitors_map, &mon_info->hmap_node); free(mon_info); } } @@ -3369,17 +3423,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 *local_svc_monitors_map, + struct hmap *ic_learned_svc_monitors_map) { - 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, + local_svc_monitors_map, ic_learned_svc_monitors_map); build_lswitch_lbs_from_lrouter(lr_datapaths, lb_dps_map, lb_group_dps_map); } @@ -7950,7 +8006,7 @@ 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 svc_monitors_map_data *svc_mons_data) { const struct ovn_northd_lb *lb = lb_dps->lb; for (size_t i = 0; i < lb->n_vips; i++) { @@ -7966,8 +8022,8 @@ build_lb_rules(struct lflow_table *lflows, struct ovn_lb_datapaths *lb_dps, const char *meter = NULL; bool reject = build_lb_vip_actions(lb, lb_vip, lb_vip_nb, action, lb->selection_fields, - NULL, NULL, true, - svc_monitor_map); + NULL, NULL, + svc_mons_data, true); ds_put_format(match, "ct.new && %s.dst == %s", ip_match, lb_vip->vip_str); @@ -11951,7 +12007,7 @@ 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 svc_monitors_map_data *svc_mons_data) { const struct ovn_northd_lb *lb = lb_dps->lb; bool ipv4 = lb_vip->address_family == AF_INET; @@ -11973,9 +12029,11 @@ build_lrouter_nat_flows_for_lb( ds_clear(action); 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); + lb->selection_fields, + &skip_snat_act, + &force_snat_act, + svc_mons_data, + false); /* Higher priority rules are added for load-balancing in DNAT * table. For every match (on a VIP[:port]), we add two flows. @@ -12133,7 +12191,7 @@ 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 svc_monitors_map_data *svc_mons_data, struct ds *match, struct ds *action) { if (!lb_dps->n_nb_ls) { @@ -12177,7 +12235,7 @@ 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, svc_mons_data); } /* If there are any load balancing rules, we should send the packet to @@ -12249,7 +12307,7 @@ 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 svc_monitors_map_data *svc_mons_data, struct ds *match, struct ds *action) { size_t index; @@ -12265,7 +12323,7 @@ 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); + svc_mons_data); build_lrouter_allow_vip_traffic_template(lflows, lb_dps, lb_vip, lb, lr_datapaths); @@ -17349,7 +17407,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; @@ -17613,6 +17672,11 @@ build_lflows_thread(void *arg) if (stop_parallel_processing()) { return NULL; } + struct svc_monitors_map_data svc_mons_data; + svc_mons_data = svc_monitors_map_data_init( + lsi->local_svc_monitor_map, + lsi->ic_learned_svc_monitor_map, + NULL); build_lswitch_arp_nd_service_monitor(lb_dps, lsi->ls_ports, lsi->svc_monitor_mac, @@ -17626,12 +17690,12 @@ build_lflows_thread(void *arg) lsi->meter_groups, lsi->lr_datapaths, lsi->lr_stateful_table, - lsi->svc_monitor_map, + &svc_mons_data, &lsi->match, &lsi->actions); build_lswitch_flows_for_lb(lb_dps, lsi->lflows, lsi->meter_groups, lsi->ls_datapaths, - lsi->svc_monitor_map, + &svc_mons_data, &lsi->match, &lsi->actions); } } @@ -17725,7 +17789,7 @@ 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 svc_monitors_map_data *svc_mons_data, const struct sset *bfd_ports, const struct chassis_features *features, const char *svc_monitor_mac, @@ -17760,7 +17824,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 = + svc_mons_data->local_svc_monitors_map; + lsiv[index].ic_learned_svc_monitor_map = + svc_mons_data->ic_learned_svc_monitors_map; lsiv[index].bfd_ports = bfd_ports; lsiv[index].features = features; lsiv[index].svc_check_match = svc_check_match; @@ -17804,7 +17871,10 @@ 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 = + svc_mons_data->local_svc_monitors_map, + .ic_learned_svc_monitor_map = + svc_mons_data->ic_learned_svc_monitors_map, .bfd_ports = bfd_ports, .features = features, .svc_check_match = svc_check_match, @@ -17861,11 +17931,11 @@ 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, + svc_mons_data, &lsi.match, &lsi.actions); build_lswitch_flows_for_lb(lb_dps, lsi.lflows, lsi.meter_groups, lsi.ls_datapaths, - lsi.svc_monitor_map, + svc_mons_data, &lsi.match, &lsi.actions); } stopwatch_stop(LFLOWS_LBS_STOPWATCH_NAME, time_msec()); @@ -17963,6 +18033,12 @@ void build_lflows(struct ovsdb_idl_txn *ovnsb_txn, struct lflow_input *input_data, struct lflow_table *lflows) { + struct svc_monitors_map_data svc_mons_data = + svc_monitors_map_data_init( + input_data->local_svc_monitors_map, + input_data->ic_learned_svc_monitors_map, + input_data->ic_learned_svc_monitors_lflow_ref); + build_lswitch_and_lrouter_flows(input_data->ls_datapaths, input_data->lr_datapaths, input_data->ls_ports, @@ -17973,7 +18049,7 @@ void build_lflows(struct ovsdb_idl_txn *ovnsb_txn, lflows, input_data->meter_groups, input_data->lb_datapaths_map, - input_data->local_svc_monitors_map, + &svc_mons_data, input_data->bfd_ports, input_data->features, input_data->svc_monitor_mac, @@ -18198,6 +18274,12 @@ lflow_handle_northd_lb_changes(struct ovsdb_idl_txn *ovnsb_txn, { struct ovn_lb_datapaths *lb_dps; struct hmapx_node *hmapx_node; + + struct svc_monitors_map_data svc_mons_data = + svc_monitors_map_data_init(lflow_input->local_svc_monitors_map, + lflow_input->ic_learned_svc_monitors_map, + NULL); + HMAPX_FOR_EACH (hmapx_node, &trk_lbs->deleted) { lb_dps = hmapx_node->data; @@ -18229,12 +18311,12 @@ lflow_handle_northd_lb_changes(struct ovsdb_idl_txn *ovnsb_txn, lflow_input->meter_groups, lflow_input->lr_datapaths, lflow_input->lr_stateful_table, - lflow_input->local_svc_monitors_map, + &svc_mons_data, &match, &actions); build_lswitch_flows_for_lb(lb_dps, lflows, lflow_input->meter_groups, lflow_input->ls_datapaths, - lflow_input->local_svc_monitors_map, + &svc_mons_data, &match, &actions); ds_destroy(&match); @@ -18961,14 +19043,12 @@ 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->local_svc_monitors_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->local_svc_monitors_map, + input_data->ic_learned_svc_monitors_map); build_lb_count_dps(&data->lb_datapaths_map, ods_size(&data->ls_datapaths), ods_size(&data->lr_datapaths)); diff --git a/northd/northd.h b/northd/northd.h index 6922c19e8..75f03e69b 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -828,6 +828,12 @@ struct parsed_route *parsed_route_add( const struct ovn_port *tracked_port, struct hmap *routes); +struct svc_monitors_map_data { + const struct hmap *local_svc_monitors_map; + const struct hmap *ic_learned_svc_monitors_map; + struct lflow_ref *lflow_ref; +}; + bool find_route_outport(const struct hmap *lr_ports, const char *output_port, const char *ip_prefix, const char *nexthop, bool is_ipv4, -- 2.48.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
