From patchwork Thu May 5 14:00:08 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: 1626987 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::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (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 4KvFhd6kJBz9sBB for ; Fri, 6 May 2022 00:00:33 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 342EB8403B; Thu, 5 May 2022 14:00:31 +0000 (UTC) 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 ZJZBKTE_Ig9Y; Thu, 5 May 2022 14:00:28 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id ADF5584081; Thu, 5 May 2022 14:00:27 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A94D3C0083; Thu, 5 May 2022 14:00:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3F97CC002D for ; Thu, 5 May 2022 14:00:22 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 2E8C68403B for ; Thu, 5 May 2022 14:00:22 +0000 (UTC) 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 LjPGuhO1JDto for ; Thu, 5 May 2022 14:00:21 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from chinatelecom.cn (prt-mail.chinatelecom.cn [42.123.76.222]) by smtp1.osuosl.org (Postfix) with ESMTP id 840D484037 for ; Thu, 5 May 2022 14:00:21 +0000 (UTC) HMM_SOURCE_IP: 172.18.0.48:38042.23832497 HMM_ATTACHE_NUM: 0000 HMM_SOURCE_TYPE: SMTP Received: from clientip-101.229.163.228 (unknown [172.18.0.48]) by chinatelecom.cn (HERMES) with SMTP id DE45B2800BE; Thu, 5 May 2022 22:00:13 +0800 (CST) X-189-SAVE-TO-SEND: wenxu@chinatelecom.cn Received: from ([172.18.0.48]) by app0024 with ESMTP id b7bfe87ae7f14966ab4917af832bf9c6 for dev@openvswitch.org; Thu, 05 May 2022 22:00:15 CST X-Transaction-ID: b7bfe87ae7f14966ab4917af832bf9c6 X-Real-From: wenxu@chinatelecom.cn X-Receive-IP: 172.18.0.48 X-MEDUSA-Status: 0 From: wenxu@chinatelecom.cn To: dev@openvswitch.org, pvalerio@redhat.com, i.maximets@ovn.org Date: Thu, 5 May 2022 10:00:08 -0400 Message-Id: <1651759208-28638-2-git-send-email-wenxu@chinatelecom.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1651759208-28638-1-git-send-email-wenxu@chinatelecom.cn> References: <1651759208-28638-1-git-send-email-wenxu@chinatelecom.cn> Subject: [ovs-dev] [PATCH v3 2/2] conntrack: limit port clash resolution attempts 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 In case almost or all available ports are taken, clash resolution can take a very long time, resulting in pmd lockup. This can happen when many to-be-natted hosts connect to same destination:port (e.g. a proxy) and all connections pass the same SNAT. Pick a random offset in the acceptable range, then try ever smaller number of adjacent port numbers, until either the limit is reached or a useable port was found. This results in at most 248 attempts (128 + 64 + 32 + 16 + 8, i.e. 4 restarts with new search offset) instead of 64000+. Signed-off-by: wenxu Acked-by: Paolo Valerio --- lib/conntrack.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/conntrack.c b/lib/conntrack.c index 6b63fe6..b243370 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -2357,9 +2357,24 @@ nat_get_unique_l4(struct conntrack *ct, struct conn *nat_conn, ovs_be16 *port, uint16_t curr, uint16_t min, uint16_t max) { + static const unsigned int max_attempts = 128; + uint16_t range = max - min + 1; + unsigned int attempts; uint16_t orig = curr; + unsigned int i = 0; + attempts = range; + if (attempts > max_attempts) { + attempts = max_attempts; + } + +another_round: + i = 0; FOR_EACH_PORT_IN_RANGE (curr, min, max) { + if (i++ >= attempts) { + break; + } + *port = htons(curr); if (!conn_lookup(ct, &nat_conn->rev_key, time_msec(), NULL, NULL)) { @@ -2367,6 +2382,12 @@ nat_get_unique_l4(struct conntrack *ct, struct conn *nat_conn, } } + if (attempts < range && attempts >= 16) { + attempts /= 2; + curr = min + (random_uint32() % range); + goto another_round; + } + *port = htons(orig); return false;