From patchwork Tue Feb 7 11:43:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Maximets X-Patchwork-Id: 1738901 X-Patchwork-Delegate: mmichels@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PB1VR1gtyz23jB for ; Tue, 7 Feb 2023 22:43:43 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 35FFE40A2A; Tue, 7 Feb 2023 11:43:40 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 35FFE40A2A X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eg3rk56GHyig; Tue, 7 Feb 2023 11:43:37 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id 162A340990; Tue, 7 Feb 2023 11:43:35 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 162A340990 Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id D09ADC0033; Tue, 7 Feb 2023 11:43:34 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4EF05C002B for ; Tue, 7 Feb 2023 11:43:34 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id D2619813BC for ; Tue, 7 Feb 2023 11:43:23 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org D2619813BC X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6xuB1R1REgjd for ; Tue, 7 Feb 2023 11:43:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org D117081E0E Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by smtp1.osuosl.org (Postfix) with ESMTPS id D117081E0E for ; Tue, 7 Feb 2023 11:43:20 +0000 (UTC) Received: (Authenticated sender: i.maximets@ovn.org) by mail.gandi.net (Postfix) with ESMTPSA id 05BB91C0003; Tue, 7 Feb 2023 11:43:17 +0000 (UTC) From: Ilya Maximets To: ovs-dev@openvswitch.org Date: Tue, 7 Feb 2023 12:43:00 +0100 Message-Id: <20230207114302.1908836-7-i.maximets@ovn.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230207114302.1908836-1-i.maximets@ovn.org> References: <20230207114302.1908836-1-i.maximets@ovn.org> MIME-Version: 1.0 Cc: Dumitru Ceara , Ilya Maximets Subject: [ovs-dev] [PATCH ovn v2 6/8] northd: Create logical flows with datapath groups. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" The same pattern of logical flow creation is repeated multiple times in the code: 1. Calculate the hash. 2. Lock the hash. 3. Iterate over all datapaths in a group. 4. Create an lflow with ovn_lflow_add_at_with_hash() for the first time. 5. Add all other datapaths with ovn_dp_group_add_with_reference(). 6. Unlock the hash. Adding an extra 'dp_bitmap' parameter to the logical flow creation functions and a new ovn_lflow_add_with_dp_group() wrapper, so we can create a flow with all the datapaths we need at once and get rid of most of the code duplications. Signed-off-by: Ilya Maximets --- northd/northd.c | 292 +++++++++++++++--------------------------------- 1 file changed, 90 insertions(+), 202 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 16a208d85..941085e0f 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -5181,14 +5181,19 @@ static thread_local size_t thread_lflow_counter = 0; * hash lock is already taken. */ static bool ovn_dp_group_add_with_reference(struct ovn_lflow *lflow_ref, - struct ovn_datapath *od) + const struct ovn_datapath *od, + const unsigned long *dp_bitmap) OVS_REQUIRES(fake_hash_mutex) { if (!lflow_ref) { return false; } - - bitmap_set1(lflow_ref->dpg_bitmap, od->index); + if (od) { + bitmap_set1(lflow_ref->dpg_bitmap, od->index); + } + if (dp_bitmap) { + bitmap_or(lflow_ref->dpg_bitmap, dp_bitmap, n_datapaths); + } return true; } @@ -5196,7 +5201,8 @@ ovn_dp_group_add_with_reference(struct ovn_lflow *lflow_ref, * Version to use when hash bucket locking is NOT required. */ static struct ovn_lflow * -do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od, +do_ovn_lflow_add(struct hmap *lflow_map, const struct ovn_datapath *od, + const unsigned long *dp_bitmap, uint32_t hash, enum ovn_stage stage, uint16_t priority, const char *match, const char *actions, const char *io_port, const struct ovsdb_idl_row *stage_hint, @@ -5210,7 +5216,7 @@ do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od, old_lflow = ovn_lflow_find(lflow_map, NULL, stage, priority, match, actions, ctrl_meter, hash); if (old_lflow) { - ovn_dp_group_add_with_reference(old_lflow, od); + ovn_dp_group_add_with_reference(old_lflow, od, dp_bitmap); return old_lflow; } @@ -5223,7 +5229,9 @@ do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od, io_port ? xstrdup(io_port) : NULL, nullable_xstrdup(ctrl_meter), ovn_lflow_hint(stage_hint), where); - bitmap_set1(lflow->dpg_bitmap, od->index); + + ovn_dp_group_add_with_reference(lflow, od, dp_bitmap); + if (parallelization_state != STATE_USE_PARALLELIZATION) { hmap_insert(lflow_map, &lflow->hmap_node, hash); } else { @@ -5237,7 +5245,9 @@ do_ovn_lflow_add(struct hmap *lflow_map, struct ovn_datapath *od, * Version to use when hash is pre-computed and a hash bucket is already * locked if necessary. */ static struct ovn_lflow * -ovn_lflow_add_at_with_hash(struct hmap *lflow_map, struct ovn_datapath *od, +ovn_lflow_add_at_with_hash(struct hmap *lflow_map, + const struct ovn_datapath *od, + const unsigned long *dp_bitmap, enum ovn_stage stage, uint16_t priority, const char *match, const char *actions, const char *io_port, const char *ctrl_meter, @@ -5247,16 +5257,19 @@ ovn_lflow_add_at_with_hash(struct hmap *lflow_map, struct ovn_datapath *od, { struct ovn_lflow *lflow; - ovs_assert(ovn_stage_to_datapath_type(stage) == ovn_datapath_get_type(od)); + ovs_assert(!od || + ovn_stage_to_datapath_type(stage) == ovn_datapath_get_type(od)); - lflow = do_ovn_lflow_add(lflow_map, od, hash, stage, priority, match, - actions, io_port, stage_hint, where, ctrl_meter); + lflow = do_ovn_lflow_add(lflow_map, od, dp_bitmap, hash, stage, priority, + match, actions, io_port, stage_hint, where, + ctrl_meter); return lflow; } /* Adds a row with the specified contents to the Logical_Flow table. */ static void -ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, +ovn_lflow_add_at(struct hmap *lflow_map, const struct ovn_datapath *od, + const unsigned long *dp_bitmap, enum ovn_stage stage, uint16_t priority, const char *match, const char *actions, const char *io_port, const char *ctrl_meter, @@ -5272,8 +5285,9 @@ ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od, actions); hash_lock = lflow_hash_lock(lflow_map, hash); - ovn_lflow_add_at_with_hash(lflow_map, od, stage, priority, match, actions, - io_port, ctrl_meter, stage_hint, where, hash); + ovn_lflow_add_at_with_hash(lflow_map, od, dp_bitmap, stage, priority, + match, actions, io_port, ctrl_meter, + stage_hint, where, hash); lflow_hash_unlock(hash_lock); } @@ -5283,7 +5297,8 @@ __ovn_lflow_add_default_drop(struct hmap *lflow_map, enum ovn_stage stage, const char *where) { - ovn_lflow_add_at(lflow_map, od, stage, 0, "1", debug_drop_action(), + ovn_lflow_add_at(lflow_map, od, NULL, stage, 0, "1", + debug_drop_action(), NULL, NULL, NULL, where ); } @@ -5291,14 +5306,19 @@ __ovn_lflow_add_default_drop(struct hmap *lflow_map, #define ovn_lflow_add_with_hint__(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, \ ACTIONS, IN_OUT_PORT, CTRL_METER, \ STAGE_HINT) \ - ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ + ovn_lflow_add_at(LFLOW_MAP, OD, NULL, STAGE, PRIORITY, MATCH, ACTIONS, \ IN_OUT_PORT, CTRL_METER, STAGE_HINT, OVS_SOURCE_LOCATOR) #define ovn_lflow_add_with_hint(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, \ ACTIONS, STAGE_HINT) \ - ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ + ovn_lflow_add_at(LFLOW_MAP, OD, NULL, STAGE, PRIORITY, MATCH, ACTIONS, \ NULL, NULL, STAGE_HINT, OVS_SOURCE_LOCATOR) +#define ovn_lflow_add_with_dp_group(LFLOW_MAP, DP_BITMAP, STAGE, PRIORITY, \ + MATCH, ACTIONS, STAGE_HINT) \ + ovn_lflow_add_at(LFLOW_MAP, NULL, DP_BITMAP, STAGE, PRIORITY, MATCH, \ + ACTIONS, NULL, NULL, STAGE_HINT, OVS_SOURCE_LOCATOR) + #define ovn_lflow_add_default_drop(LFLOW_MAP, OD, STAGE) \ __ovn_lflow_add_default_drop(LFLOW_MAP, OD, STAGE, OVS_SOURCE_LOCATOR) @@ -5316,11 +5336,11 @@ __ovn_lflow_add_default_drop(struct hmap *lflow_map, #define ovn_lflow_add_with_lport_and_hint(LFLOW_MAP, OD, STAGE, PRIORITY, \ MATCH, ACTIONS, IN_OUT_PORT, \ STAGE_HINT) \ - ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ + ovn_lflow_add_at(LFLOW_MAP, OD, NULL, STAGE, PRIORITY, MATCH, ACTIONS, \ IN_OUT_PORT, NULL, STAGE_HINT, OVS_SOURCE_LOCATOR) #define ovn_lflow_add(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS) \ - ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ + ovn_lflow_add_at(LFLOW_MAP, OD, NULL, STAGE, PRIORITY, MATCH, ACTIONS, \ NULL, NULL, NULL, OVS_SOURCE_LOCATOR) #define ovn_lflow_metered(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \ @@ -7038,6 +7058,10 @@ build_lb_rules_pre_stateful(struct hmap *lflows, struct ovn_northd_lb *lb, bool ct_lb_mark, struct ds *match, struct ds *action) { + if (!lb->n_nb_ls) { + return; + } + for (size_t i = 0; i < lb->n_vips; i++) { struct ovn_lb_vip *lb_vip = &lb->vips[i]; ds_clear(action); @@ -7082,26 +7106,9 @@ build_lb_rules_pre_stateful(struct hmap *lflows, struct ovn_northd_lb *lb, ds_put_format(match, " && %s.dst == %s", proto, lb_vip->port_str); } - struct ovn_lflow *lflow_ref = NULL; - uint32_t hash = ovn_logical_flow_hash( - ovn_stage_get_table(S_SWITCH_IN_PRE_STATEFUL), - ovn_stage_get_pipeline(S_SWITCH_IN_PRE_STATEFUL), 120, - ds_cstr(match), ds_cstr(action)); - struct ovs_mutex *hash_lock = lflow_hash_lock(lflows, hash); - size_t index; - - BITMAP_FOR_EACH_1 (index, n_datapaths, lb->nb_ls_map) { - struct ovn_datapath *od = datapaths_array[index]; - - if (!ovn_dp_group_add_with_reference(lflow_ref, od)) { - lflow_ref = ovn_lflow_add_at_with_hash( - lflows, od, S_SWITCH_IN_PRE_STATEFUL, 120, - ds_cstr(match), ds_cstr(action), - NULL, NULL, &lb->nlb->header_, - OVS_SOURCE_LOCATOR, hash); - } - } - lflow_hash_unlock(hash_lock); + ovn_lflow_add_with_dp_group( + lflows, lb->nb_ls_map, S_SWITCH_IN_PRE_STATEFUL, 120, + ds_cstr(match), ds_cstr(action), &lb->nlb->header_); } } @@ -7145,34 +7152,18 @@ build_lb_rules_pre_stateful(struct hmap *lflows, struct ovn_northd_lb *lb, static void build_lb_affinity_lr_flows(struct hmap *lflows, struct ovn_northd_lb *lb, struct ovn_lb_vip *lb_vip, char *new_lb_match, - char *lb_action, unsigned long *dp_bitmap) + char *lb_action, const unsigned long *dp_bitmap) { - if (!lb->affinity_timeout) { + if (!lb->affinity_timeout || + bitmap_is_all_zeros(dp_bitmap, n_datapaths)) { return; } static char *aff_check = REGBIT_KNOWN_LB_SESSION" = chk_lb_aff(); next;"; - struct ovn_lflow *lflow_ref_aff_check = NULL; - /* Check if we have already a enstablished connection for this - * tuple and we are in affinity timeslot. */ - uint32_t hash_aff_check = ovn_logical_flow_hash( - ovn_stage_get_table(S_ROUTER_IN_LB_AFF_CHECK), - ovn_stage_get_pipeline(S_ROUTER_IN_LB_AFF_CHECK), 100, - new_lb_match, aff_check); - struct ovs_mutex *hash_lock = lflow_hash_lock(lflows, hash_aff_check); - size_t index; - BITMAP_FOR_EACH_1 (index, n_datapaths, dp_bitmap) { - struct ovn_datapath *od = datapaths_array[index]; - - if (!ovn_dp_group_add_with_reference(lflow_ref_aff_check, od)) { - lflow_ref_aff_check = ovn_lflow_add_at_with_hash( - lflows, od, S_ROUTER_IN_LB_AFF_CHECK, 100, - new_lb_match, aff_check, NULL, NULL, &lb->nlb->header_, - OVS_SOURCE_LOCATOR, hash_aff_check); - } - } - lflow_hash_unlock(hash_lock); + ovn_lflow_add_with_dp_group( + lflows, dp_bitmap, S_ROUTER_IN_LB_AFF_CHECK, 100, + new_lb_match, aff_check, &lb->nlb->header_); struct ds aff_action = DS_EMPTY_INITIALIZER; struct ds aff_action_learn = DS_EMPTY_INITIALIZER; @@ -7269,48 +7260,16 @@ build_lb_affinity_lr_flows(struct hmap *lflows, struct ovn_northd_lb *lb, ds_put_format(&aff_action_learn, ", timeout = %d); /* drop */", lb->affinity_timeout); - struct ovn_lflow *lflow_ref_aff_learn = NULL; - uint32_t hash_aff_learn = ovn_logical_flow_hash( - ovn_stage_get_table(S_ROUTER_IN_LB_AFF_LEARN), - ovn_stage_get_pipeline(S_ROUTER_IN_LB_AFF_LEARN), - 100, ds_cstr(&aff_match_learn), ds_cstr(&aff_action_learn)); - struct ovs_mutex *hash_lock_learn = lflow_hash_lock(lflows, - hash_aff_learn); - - BITMAP_FOR_EACH_1 (index, n_datapaths, dp_bitmap) { - struct ovn_datapath *od = datapaths_array[index]; - - /* Forward to OFTABLE_CHK_LB_AFFINITY table to store flow tuple. */ - if (!ovn_dp_group_add_with_reference(lflow_ref_aff_learn, od)) { - lflow_ref_aff_learn = ovn_lflow_add_at_with_hash( - lflows, od, S_ROUTER_IN_LB_AFF_LEARN, 100, - ds_cstr(&aff_match_learn), ds_cstr(&aff_action_learn), - NULL, NULL, &lb->nlb->header_, OVS_SOURCE_LOCATOR, - hash_aff_learn); - } - } - lflow_hash_unlock(hash_lock_learn); - - struct ovn_lflow *lflow_ref_aff_lb = NULL; - uint32_t hash_aff_lb = ovn_logical_flow_hash( - ovn_stage_get_table(S_ROUTER_IN_DNAT), - ovn_stage_get_pipeline(S_ROUTER_IN_DNAT), - 150, ds_cstr(&aff_match), ds_cstr(&aff_action)); - struct ovs_mutex *hash_lock_lb = lflow_hash_lock(lflows, hash_aff_lb); + /* Forward to OFTABLE_CHK_LB_AFFINITY table to store flow tuple. */ + ovn_lflow_add_with_dp_group( + lflows, dp_bitmap, S_ROUTER_IN_LB_AFF_LEARN, 100, + ds_cstr(&aff_match_learn), ds_cstr(&aff_action_learn), + &lb->nlb->header_); - BITMAP_FOR_EACH_1 (index, n_datapaths, dp_bitmap) { - struct ovn_datapath *od = datapaths_array[index]; - - /* Use already selected backend within affinity timeslot. */ - if (!ovn_dp_group_add_with_reference(lflow_ref_aff_lb, od)) { - lflow_ref_aff_lb = ovn_lflow_add_at_with_hash( - lflows, od, S_ROUTER_IN_DNAT, 150, - ds_cstr(&aff_match), ds_cstr(&aff_action), NULL, NULL, - &lb->nlb->header_, OVS_SOURCE_LOCATOR, - hash_aff_lb); - } - } - lflow_hash_unlock(hash_lock_lb); + /* Use already selected backend within affinity timeslot. */ + ovn_lflow_add_with_dp_group( + lflows, dp_bitmap, S_ROUTER_IN_DNAT, 150, + ds_cstr(&aff_match), ds_cstr(&aff_action), &lb->nlb->header_); ds_truncate(&aff_action, aff_action_len); ds_truncate(&aff_action_learn, aff_action_learn_len); @@ -7369,7 +7328,7 @@ static void build_lb_affinity_ls_flows(struct hmap *lflows, struct ovn_northd_lb *lb, struct ovn_lb_vip *lb_vip) { - if (!lb->affinity_timeout) { + if (!lb->affinity_timeout || !lb->n_nb_ls) { return; } @@ -7390,27 +7349,10 @@ build_lb_affinity_ls_flows(struct hmap *lflows, struct ovn_northd_lb *lb, } static char *aff_check = REGBIT_KNOWN_LB_SESSION" = chk_lb_aff(); next;"; - struct ovn_lflow *lflow_ref_aff_check = NULL; - /* Check if we have already a enstablished connection for this - * tuple and we are in affinity timeslot. */ - uint32_t hash_aff_check = ovn_logical_flow_hash( - ovn_stage_get_table(S_SWITCH_IN_LB_AFF_CHECK), - ovn_stage_get_pipeline(S_SWITCH_IN_LB_AFF_CHECK), 100, - ds_cstr(&new_lb_match), aff_check); - struct ovs_mutex *hash_lock = lflow_hash_lock(lflows, hash_aff_check); - size_t index; - - BITMAP_FOR_EACH_1 (index, n_datapaths, lb->nb_ls_map) { - struct ovn_datapath *od = datapaths_array[index]; - if (!ovn_dp_group_add_with_reference(lflow_ref_aff_check, od)) { - lflow_ref_aff_check = ovn_lflow_add_at_with_hash( - lflows, od, S_SWITCH_IN_LB_AFF_CHECK, 100, - ds_cstr(&new_lb_match), aff_check, NULL, NULL, - &lb->nlb->header_, OVS_SOURCE_LOCATOR, hash_aff_check); - } - } - lflow_hash_unlock(hash_lock); + ovn_lflow_add_with_dp_group( + lflows, lb->nb_ls_map, S_SWITCH_IN_LB_AFF_CHECK, 100, + ds_cstr(&new_lb_match), aff_check, &lb->nlb->header_); ds_destroy(&new_lb_match); struct ds aff_action = DS_EMPTY_INITIALIZER; @@ -7496,48 +7438,16 @@ build_lb_affinity_ls_flows(struct hmap *lflows, struct ovn_northd_lb *lb, ds_put_format(&aff_action_learn, ", timeout = %d); /* drop */", lb->affinity_timeout); - struct ovn_lflow *lflow_ref_aff_learn = NULL; - uint32_t hash_aff_learn = ovn_logical_flow_hash( - ovn_stage_get_table(S_SWITCH_IN_LB_AFF_LEARN), - ovn_stage_get_pipeline(S_SWITCH_IN_LB_AFF_LEARN), - 100, ds_cstr(&aff_match_learn), ds_cstr(&aff_action_learn)); - struct ovs_mutex *hash_lock_learn = lflow_hash_lock(lflows, - hash_aff_learn); + /* Forward to OFTABLE_CHK_LB_AFFINITY table to store flow tuple. */ + ovn_lflow_add_with_dp_group( + lflows, lb->nb_ls_map, S_SWITCH_IN_LB_AFF_LEARN, 100, + ds_cstr(&aff_match_learn), ds_cstr(&aff_action_learn), + &lb->nlb->header_); - BITMAP_FOR_EACH_1 (index, n_datapaths, lb->nb_ls_map) { - struct ovn_datapath *od = datapaths_array[index]; - - /* Forward to OFTABLE_CHK_LB_AFFINITY table to store flow tuple. */ - if (!ovn_dp_group_add_with_reference(lflow_ref_aff_learn, od)) { - lflow_ref_aff_learn = ovn_lflow_add_at_with_hash( - lflows, od, S_SWITCH_IN_LB_AFF_LEARN, 100, - ds_cstr(&aff_match_learn), ds_cstr(&aff_action_learn), - NULL, NULL, &lb->nlb->header_, OVS_SOURCE_LOCATOR, - hash_aff_learn); - } - } - lflow_hash_unlock(hash_lock_learn); - - struct ovn_lflow *lflow_ref_aff_lb = NULL; - uint32_t hash_aff_lb = ovn_logical_flow_hash( - ovn_stage_get_table(S_SWITCH_IN_LB), - ovn_stage_get_pipeline(S_SWITCH_IN_LB), - 150, ds_cstr(&aff_match), ds_cstr(&aff_action)); - struct ovs_mutex *hash_lock_lb = lflow_hash_lock(lflows, hash_aff_lb); - - BITMAP_FOR_EACH_1 (index, n_datapaths, lb->nb_ls_map) { - struct ovn_datapath *od = datapaths_array[index]; - - /* Use already selected backend within affinity timeslot. */ - if (!ovn_dp_group_add_with_reference(lflow_ref_aff_lb, od)) { - lflow_ref_aff_lb = ovn_lflow_add_at_with_hash( - lflows, od, S_SWITCH_IN_LB, 150, - ds_cstr(&aff_match), ds_cstr(&aff_action), NULL, NULL, - &lb->nlb->header_, OVS_SOURCE_LOCATOR, - hash_aff_lb); - } - } - lflow_hash_unlock(hash_lock_lb); + /* Use already selected backend within affinity timeslot. */ + ovn_lflow_add_with_dp_group( + lflows, lb->nb_ls_map, S_SWITCH_IN_LB, 150, + ds_cstr(&aff_match), ds_cstr(&aff_action), &lb->nlb->header_); ds_truncate(&aff_action, aff_action_len); ds_truncate(&aff_action_learn, aff_action_learn_len); @@ -7619,9 +7529,10 @@ build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb, meter = copp_meter_get(COPP_REJECT, od->nbs->copp, meter_groups); } - if (meter || !ovn_dp_group_add_with_reference(lflow_ref, od)) { + if (meter || !ovn_dp_group_add_with_reference(lflow_ref, + od, NULL)) { struct ovn_lflow *lflow = ovn_lflow_add_at_with_hash( - lflows, od, S_SWITCH_IN_LB, priority, + lflows, od, NULL, S_SWITCH_IN_LB, priority, ds_cstr(match), ds_cstr(action), NULL, meter, &lb->nlb->header_, OVS_SOURCE_LOCATOR, hash); @@ -10625,14 +10536,18 @@ build_distr_lrouter_nat_flows_for_lb(struct lrouter_nat_lb_flows_ctx *ctx, static void build_gw_lrouter_nat_flows_for_lb(struct lrouter_nat_lb_flows_ctx *ctx, enum lrouter_nat_lb_flow_type type, - unsigned long *dp_bitmap) + const unsigned long *dp_bitmap) { - struct ovn_lflow *new_lflow_ref = NULL, *est_lflow_ref = NULL; + struct ovn_lflow *new_lflow_ref = NULL; struct lrouter_nat_lb_flow *new_flow = &ctx->new[type]; struct lrouter_nat_lb_flow *est_flow = &ctx->est[type]; struct ovs_mutex *hash_lock; size_t index; + if (bitmap_is_all_zeros(dp_bitmap, n_datapaths)) { + return; + } + hash_lock = lflow_hash_lock(ctx->lflows, new_flow->hash); BITMAP_FOR_EACH_1 (index, n_datapaths, dp_bitmap) { struct ovn_datapath *od = datapaths_array[index]; @@ -10645,8 +10560,8 @@ build_gw_lrouter_nat_flows_for_lb(struct lrouter_nat_lb_flows_ctx *ctx, } if (meter || - !ovn_dp_group_add_with_reference(new_lflow_ref, od)) { - lflow = ovn_lflow_add_at_with_hash(ctx->lflows, od, + !ovn_dp_group_add_with_reference(new_lflow_ref, od, NULL)) { + lflow = ovn_lflow_add_at_with_hash(ctx->lflows, od, NULL, S_ROUTER_IN_DNAT, ctx->prio, ds_cstr(ctx->new_match), new_flow->action, NULL, meter, &ctx->lb->nlb->header_, OVS_SOURCE_LOCATOR, new_flow->hash); @@ -10655,18 +10570,9 @@ build_gw_lrouter_nat_flows_for_lb(struct lrouter_nat_lb_flows_ctx *ctx, } lflow_hash_unlock(hash_lock); - hash_lock = lflow_hash_lock(ctx->lflows, est_flow->hash); - BITMAP_FOR_EACH_1 (index, n_datapaths, dp_bitmap) { - struct ovn_datapath *od = datapaths_array[index]; - - if (!ovn_dp_group_add_with_reference(est_lflow_ref, od)) { - est_lflow_ref = ovn_lflow_add_at_with_hash(ctx->lflows, od, - S_ROUTER_IN_DNAT, ctx->prio, ds_cstr(ctx->est_match), - est_flow->action, NULL, NULL, &ctx->lb->nlb->header_, - OVS_SOURCE_LOCATOR, est_flow->hash); - } - } - lflow_hash_unlock(hash_lock); + ovn_lflow_add_with_dp_group( + ctx->lflows, dp_bitmap, S_ROUTER_IN_DNAT, ctx->prio, + ds_cstr(ctx->est_match), est_flow->action, &ctx->lb->nlb->header_); } static void @@ -10958,27 +10864,9 @@ build_lrouter_defrag_flows_for_lb(struct ovn_northd_lb *lb, ds_put_format(&defrag_actions, "ct_dnat;"); - struct ovn_lflow *lflow_ref = NULL; - uint32_t hash = ovn_logical_flow_hash( - ovn_stage_get_table(S_ROUTER_IN_DEFRAG), - ovn_stage_get_pipeline(S_ROUTER_IN_DEFRAG), prio, - ds_cstr(match), ds_cstr(&defrag_actions)); - struct ovs_mutex *hash_lock = lflow_hash_lock(lflows, hash); - size_t index; - - BITMAP_FOR_EACH_1 (index, n_datapaths, lb->nb_lr_map) { - struct ovn_datapath *od = datapaths_array[index]; - - if (ovn_dp_group_add_with_reference(lflow_ref, od)) { - continue; - } - lflow_ref = ovn_lflow_add_at_with_hash(lflows, od, - S_ROUTER_IN_DEFRAG, prio, - ds_cstr(match), ds_cstr(&defrag_actions), - NULL, NULL, &lb->nlb->header_, - OVS_SOURCE_LOCATOR, hash); - } - lflow_hash_unlock(hash_lock); + ovn_lflow_add_with_dp_group( + lflows, lb->nb_lr_map, S_ROUTER_IN_DEFRAG, prio, + ds_cstr(match), ds_cstr(&defrag_actions), &lb->nlb->header_); } ds_destroy(&defrag_actions); }