From patchwork Tue Aug 2 04:01:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "wenxu@chinatelecom.cn" X-Patchwork-Id: 1662777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LxhBy3dvFz9sB4 for ; Tue, 2 Aug 2022 14:02:02 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 206AF408A0; Tue, 2 Aug 2022 04:01:59 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 206AF408A0 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Kl7EEWDvakf8; Tue, 2 Aug 2022 04:01:57 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id C70184087A; Tue, 2 Aug 2022 04:01:56 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org C70184087A Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7CFB1C0033; Tue, 2 Aug 2022 04:01:56 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0D7B2C002D for ; Tue, 2 Aug 2022 04:01:55 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id E2025607F0 for ; Tue, 2 Aug 2022 04:01:54 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org E2025607F0 X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ciXmdb5NQ3Gf for ; Tue, 2 Aug 2022 04:01:53 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 1FD5F607A4 Received: from chinatelecom.cn (prt-mail.chinatelecom.cn [42.123.76.223]) by smtp3.osuosl.org (Postfix) with ESMTP id 1FD5F607A4 for ; Tue, 2 Aug 2022 04:01:51 +0000 (UTC) HMM_SOURCE_IP: 172.18.0.188:41560.1894843666 HMM_ATTACHE_NUM: 0000 HMM_SOURCE_TYPE: SMTP Received: from clientip-180.167.241.60 (unknown [172.18.0.188]) by chinatelecom.cn (HERMES) with SMTP id D6B042800BB; Tue, 2 Aug 2022 12:01:36 +0800 (CST) X-189-SAVE-TO-SEND: wenxu@chinatelecom.cn Received: from ([172.18.0.188]) by app0023 with ESMTP id b8152f6cf3a742a1b8e7a782300fa5f9 for pvalerio@redhat.com; Tue, 02 Aug 2022 12:01:37 CST X-Transaction-ID: b8152f6cf3a742a1b8e7a782300fa5f9 X-Real-From: wenxu@chinatelecom.cn X-Receive-IP: 172.18.0.188 X-MEDUSA-Status: 0 From: wenxu@chinatelecom.cn To: pvalerio@redhat.com Date: Tue, 2 Aug 2022 00:01:07 -0400 Message-Id: <1659412867-105216-1-git-send-email-wenxu@chinatelecom.cn> X-Mailer: git-send-email 1.8.3.1 Cc: ovs-dev@openvswitch.org, i.maximets@ovn.org Subject: [ovs-dev] [PATCH v3] conntrack: narrow the scope of ct_lock in new conn setup 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: , MIME-Version: 1.0 Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: wenxu There is a big scope ct_lock for new conn setup. The ct_lock should be hold only for conns map insert and expire rculist insert. Signed-off-by: wenxu --- lib/conntrack.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index 13c5ab6..47d9aac 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -48,6 +48,7 @@ COVERAGE_DEFINE(conntrack_full); COVERAGE_DEFINE(conntrack_l3csum_err); COVERAGE_DEFINE(conntrack_l4csum_err); COVERAGE_DEFINE(conntrack_lookup_natted_miss); +COVERAGE_DEFINE(conntrack_duplicate); struct conn_lookup_ctx { struct conn_key key; @@ -1010,10 +1011,10 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt, const struct nat_action_info_t *nat_action_info, const char *helper, const struct alg_exp_node *alg_exp, enum ct_alg_ctl_type ct_alg_ctl, uint32_t tp_id) - OVS_REQUIRES(ct->ct_lock) { struct conn *nc = NULL; struct conn *nat_conn = NULL; + uint32_t nat_hash; if (!valid_new(pkt, &ctx->key)) { pkt->md.ct_state = CS_INVALID; @@ -1089,16 +1090,26 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt, nat_conn->nat_action = 0; nat_conn->alg = NULL; nat_conn->nat_conn = NULL; - uint32_t nat_hash = conn_key_hash(&nat_conn->key, ct->hash_basis); - cmap_insert(&ct->conns, &nat_conn->cm_node, nat_hash); + nat_hash = conn_key_hash(&nat_conn->key, ct->hash_basis); } nc->nat_conn = nat_conn; ovs_mutex_init_adaptive(&nc->lock); nc->conn_type = CT_CONN_TYPE_DEFAULT; atomic_flag_clear(&nc->reclaimed); + ovs_mutex_lock(&ct->ct_lock); + if (conn_key_lookup(ct, &ctx->key, ctx->hash, now, NULL, NULL)) { + ovs_mutex_unlock(&ct->ct_lock); + COVERAGE_INC(conntrack_duplicate); + ovs_mutex_destroy(&nc->lock); + goto out; + } + if (nat_conn) { + cmap_insert(&ct->conns, &nat_conn->cm_node, nat_hash); + } cmap_insert(&ct->conns, &nc->cm_node, ctx->hash); conn_expire_push_front(ct, nc); + ovs_mutex_unlock(&ct->ct_lock); atomic_count_inc(&ct->n_conn); ctx->conn = nc; /* For completeness. */ if (zl) { @@ -1117,12 +1128,13 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt, * ephemeral ports. A DOS attack should be protected against with * firewall rules or a separate firewall. Also using zone partitioning * can limit DoS impact. */ -nat_res_exhaustion: - free(nat_conn); - delete_conn__(nc); static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5); +nat_res_exhaustion: VLOG_WARN_RL(&rl, "Unable to NAT due to tuple space exhaustion - " "if DoS attack, use firewalling and/or zone partitioning."); +out: + free(nat_conn); + delete_conn__(nc); return NULL; } @@ -1437,12 +1449,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, } ovs_rwlock_unlock(&ct->resources_lock); - ovs_mutex_lock(&ct->ct_lock); - if (!conn_lookup(ct, &ctx->key, now, NULL, NULL)) { - conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info, - helper, alg_exp, ct_alg_ctl, tp_id); - } - ovs_mutex_unlock(&ct->ct_lock); + conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info, + helper, alg_exp, ct_alg_ctl, tp_id); } write_ct_md(pkt, zone, conn, &ctx->key, alg_exp);