From patchwork Mon Apr 11 03:43:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wenxu X-Patchwork-Id: 1615528 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=163.com header.i=@163.com header.a=rsa-sha256 header.s=s110527 header.b=KA7HGvE8; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KcFTv2C9fz9sBy for ; Mon, 11 Apr 2022 13:59:15 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id CC50D60B5D; Mon, 11 Apr 2022 03:59:10 +0000 (UTC) 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 S6CZo9Xy1bry; Mon, 11 Apr 2022 03:59:09 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id 91E3260B5B; Mon, 11 Apr 2022 03:59:08 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A1370C008A; Mon, 11 Apr 2022 03:59:06 +0000 (UTC) X-Original-To: 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 F094DC0033 for ; Mon, 11 Apr 2022 03:59:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id CC5C683DF0 for ; Mon, 11 Apr 2022 03:59:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp1.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=163.com 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 wED0W4AWOEsr for ; Mon, 11 Apr 2022 03:59:03 +0000 (UTC) X-Greylist: delayed 00:15:11 by SQLgrey-1.8.0 Received: from m12-15.163.com (m12-15.163.com [220.181.12.15]) by smtp1.osuosl.org (Postfix) with ESMTP id 2AD5983313 for ; Mon, 11 Apr 2022 03:59:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id; bh=lWUtcxVmIxuPVS/WID 94MlW2CaAsuIFV+4Q1x4Kfouk=; b=KA7HGvE8jJTHLkVIscJa4Zp8yYknwGMxdg ZHMy44lKSwRJ2vffJfz4gpXW1YODky9Bjcwfp/zxiTDsC5LUYzZEvWWATRBE6CXL 1apcDFBsUKeZ+CerP5u4lPjmBlB+TWbmtYX0pAJ5lig8wgsy3qxrSiToaCKC0jAl HYrxEGuYY= Received: from CentOS7.localdomain (unknown [101.229.166.98]) by smtp11 (Coremail) with SMTP id D8CowAAXsi_xo1NiPtrPAg--.7561S2; Mon, 11 Apr 2022 11:43:46 +0800 (CST) From: wenx05124561@163.com To: pvalerio@redhat.com Date: Sun, 10 Apr 2022 23:43:34 -0400 Message-Id: <1649648615-59908-1-git-send-email-wenx05124561@163.com> X-Mailer: git-send-email 1.8.3.1 X-CM-TRANSID: D8CowAAXsi_xo1NiPtrPAg--.7561S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxJw4kZF1Duw4DXFWUKFyrXrb_yoWrCryUpa y3u3sxArZ8JFZagw4DG34q9rn0yrnxAF1UKr4kJ3sakFsFvry2qF40yF1Ivas8tr929wsF qw4qq348JF4UGwUanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UD-BiUUUUU= X-Originating-IP: [101.229.166.98] X-CM-SenderInfo: hzhq5iqvrskkiwr6il2tof0z/1tbitxPfK1aEO8VHDwAAs0 Cc: dev@openvswitch.org, i.maximets@ovn.org, wenxu@chinatelecom.cn Subject: [ovs-dev] [PATCH 1/2] conntrack: remove the IP iterations in nat_get_unique_l4 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 Removing the IP iterations, and just picking the IP address with the hash base on the least-used src-ip/dst-ip/proto triple. Signed-off-by: wenxu --- lib/conntrack.c | 76 +++++++-------------------------------------------------- 1 file changed, 9 insertions(+), 67 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index 08da4dd..ac95d0f 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -2322,7 +2322,7 @@ get_addr_in_range(union ct_addr *min, union ct_addr *max, } static void -get_initial_addr(const struct conn *conn, union ct_addr *min, +find_best_addr(const struct conn *conn, union ct_addr *min, union ct_addr *max, union ct_addr *curr, uint32_t hash, bool ipv4, const struct nat_action_info_t *nat_info) @@ -2336,6 +2336,8 @@ get_initial_addr(const struct conn *conn, union ct_addr *min, } else if (nat_info->nat_action & NAT_ACTION_DST) { *curr = conn->key.dst.addr; } + } else if (!memcmp(min, max, sizeof *min)) { + *curr = *min; } else { get_addr_in_range(min, max, curr, hash, ipv4); } @@ -2352,51 +2354,6 @@ store_addr_to_key(union ct_addr *addr, struct conn_key *key, } } -static void -next_addr_in_range(union ct_addr *curr, union ct_addr *min, - union ct_addr *max, bool ipv4) -{ - if (ipv4) { - /* This check could be unified with IPv6, but let's avoid - * an unneeded memcmp() in case of IPv4. */ - if (min->ipv4 == max->ipv4) { - return; - } - - curr->ipv4 = (curr->ipv4 == max->ipv4) ? min->ipv4 - : htonl(ntohl(curr->ipv4) + 1); - } else { - if (!memcmp(min, max, sizeof *min)) { - return; - } - - if (!memcmp(curr, max, sizeof *curr)) { - *curr = *min; - return; - } - - nat_ipv6_addr_increment(&curr->ipv6, 1); - } -} - -static bool -next_addr_in_range_guarded(union ct_addr *curr, union ct_addr *min, - union ct_addr *max, union ct_addr *guard, - bool ipv4) -{ - bool exhausted; - - next_addr_in_range(curr, min, max, ipv4); - - if (ipv4) { - exhausted = (curr->ipv4 == guard->ipv4); - } else { - exhausted = !memcmp(curr, guard, sizeof *curr); - } - - return exhausted; -} - static bool nat_get_unique_l4(struct conntrack *ct, struct conn *nat_conn, ovs_be16 *port, uint16_t curr, uint16_t min, @@ -2443,9 +2400,8 @@ nat_get_unique_tuple(struct conntrack *ct, const struct conn *conn, struct conn *nat_conn, const struct nat_action_info_t *nat_info) { - union ct_addr min_addr = {0}, max_addr = {0}, curr_addr = {0}, - guard_addr = {0}; uint32_t hash = nat_range_hash(conn, ct->hash_basis, nat_info); + union ct_addr min_addr = {0}, max_addr = {0}, best_addr = {0}; bool pat_proto = conn->key.nw_proto == IPPROTO_TCP || conn->key.nw_proto == IPPROTO_UDP; uint16_t min_dport, max_dport, curr_dport; @@ -2454,12 +2410,8 @@ nat_get_unique_tuple(struct conntrack *ct, const struct conn *conn, min_addr = nat_info->min_addr; max_addr = nat_info->max_addr; - get_initial_addr(conn, &min_addr, &max_addr, &curr_addr, hash, - (conn->key.dl_type == htons(ETH_TYPE_IP)), nat_info); - - /* Save the address we started from so that - * we can stop once we reach it. */ - guard_addr = curr_addr; + find_best_addr(conn, &min_addr, &max_addr, &best_addr, hash, + (conn->key.dl_type == htons(ETH_TYPE_IP)), nat_info); set_sport_range(nat_info, &conn->key, hash, &curr_sport, &min_sport, &max_sport); @@ -2471,8 +2423,7 @@ nat_get_unique_tuple(struct conntrack *ct, const struct conn *conn, nat_conn->rev_key.dst.port = htons(curr_sport); } -another_round: - store_addr_to_key(&curr_addr, &nat_conn->rev_key, + store_addr_to_key(&best_addr, &nat_conn->rev_key, nat_info->nat_action); if (!pat_proto) { @@ -2481,7 +2432,7 @@ another_round: return true; } - goto next_addr; + return false; } bool found = false; @@ -2499,16 +2450,7 @@ another_round: return true; } - /* Check if next IP is in range and respin. Otherwise, notify - * exhaustion to the caller. */ -next_addr: - if (next_addr_in_range_guarded(&curr_addr, &min_addr, - &max_addr, &guard_addr, - conn->key.dl_type == htons(ETH_TYPE_IP))) { - return false; - } - - goto another_round; + return false; } static enum ct_update_res