From patchwork Sat Oct 9 15:28:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wenxu X-Patchwork-Id: 1538802 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=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (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 4HRTVj4q4Fz9sf8 for ; Sun, 10 Oct 2021 02:29:01 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 687F44065F; Sat, 9 Oct 2021 15:28:56 +0000 (UTC) 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 fNcemH-3nFiE; Sat, 9 Oct 2021 15:28:55 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTPS id 6A2F24044D; Sat, 9 Oct 2021 15:28:54 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 264CFC0027; Sat, 9 Oct 2021 15:28:53 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 22307C000D for ; Sat, 9 Oct 2021 15:28:49 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 044D8405C9 for ; Sat, 9 Oct 2021 15:28:49 +0000 (UTC) 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 vVQcXfkqMpj0 for ; Sat, 9 Oct 2021 15:28:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mail-m2456.qiye.163.com (mail-m2456.qiye.163.com [220.194.24.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id 9AB354058B for ; Sat, 9 Oct 2021 15:28:46 +0000 (UTC) Received: from localhost.localdomain (unknown [117.50.0.204]) by mail-m2456.qiye.163.com (Hmail) with ESMTPA id 40F477001BE; Sat, 9 Oct 2021 23:28:41 +0800 (CST) From: wenxu@ucloud.cn To: i.maximets@ovn.org, pvalerio@redhat.com Date: Sat, 9 Oct 2021 23:28:39 +0800 Message-Id: <1633793320-26048-2-git-send-email-wenxu@ucloud.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1633793320-26048-1-git-send-email-wenxu@ucloud.cn> References: <1633793320-26048-1-git-send-email-wenxu@ucloud.cn> X-HM-Spam-Status: e1kfGhgUHx5ZQUtXWQgPGg8OCBgUHx5ZQUlOS1dZCBgUCR5ZQVlLVUtZV1 kWDxoPAgseWUFZKDYvK1lXWShZQUlCN1dZLVlBSVdZDwkaFQgSH1lBWUJCT05WGUpNS0JKQk5MQ0 kZVRkRExYaEhckFA4PWVdZFhoPEhUdFFlBWVVLWQY+ X-HM-Sender-Digest: e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6N006Eww*MDIwDCofTlEjPw4U EzUwCx5VSlVKTUhITEJISElKT0JKVTMWGhIXVQweFQMOOw4YFxQOH1UYFUVZV1kSC1lBWUpKTFVO S1VLVUlLT1lXWQgBWUFNSklJNwY+ X-HM-Tid: 0a7c65aba93e8c15kuqt40f477001be Cc: dev@openvswitch.org Subject: [ovs-dev] [PATCH v6 2/3] conntrack: split the dst and src port range iterations 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 Splitting the two port range iterations instead of keeping it nested. And the dst port (in case of DNAT) range would have precedence over the src manipulation in the resolution. Signed-off-by: wenxu --- lib/conntrack.c | 65 +++++++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index 44f99f3..a6784ba 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -1036,6 +1036,17 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt, nat_action_info); if (!nat_res) { + if (nat_action_info->nat_action & NAT_ACTION_DST) { + struct nat_action_info_t tmp_nat_info; + + memset(&tmp_nat_info, 0, sizeof tmp_nat_info); + tmp_nat_info.nat_action = NAT_ACTION_SRC; + nat_res = nat_get_unique_tuple(ct, nc, nat_conn, + &tmp_nat_info); + if (!nat_res) { + goto nat_res_exhaustion; + } + } goto nat_res_exhaustion; } @@ -2258,12 +2269,12 @@ nat_range_hash(const struct conn *conn, uint32_t basis, /* Ports are stored in host byte order for convenience. */ static void -set_sport_range(const struct nat_action_info_t *ni, const struct conn_key *k, - uint32_t hash, uint16_t *curr, uint16_t *min, - uint16_t *max) +set_port_range(const struct nat_action_info_t *ni, const struct conn_key *k, + uint32_t hash, uint16_t *curr, uint16_t *min, + uint16_t *max) { - if (((ni->nat_action & NAT_ACTION_SNAT_ALL) == NAT_ACTION_SRC) || - ((ni->nat_action & NAT_ACTION_DST))) { + if ((ni->nat_action & NAT_ACTION_SRC) && + (!(ni->nat_action & NAT_ACTION_SRC_PORT))) { *curr = ntohs(k->src.port); if (*curr < 512) { *min = 1; @@ -2275,6 +2286,10 @@ set_sport_range(const struct nat_action_info_t *ni, const struct conn_key *k, *min = MIN_NAT_EPHEMERAL_PORT; *max = MAX_NAT_EPHEMERAL_PORT; } + } else if ((ni->nat_action & NAT_ACTION_DST) && + (!(ni->nat_action & NAT_ACTION_DST_PORT))) { + *curr = ntohs(k->dst.port); + *min = *max = *curr; } else { *min = ni->min_port; *max = ni->max_port; @@ -2282,21 +2297,6 @@ set_sport_range(const struct nat_action_info_t *ni, const struct conn_key *k, } } -static void -set_dport_range(const struct nat_action_info_t *ni, const struct conn_key *k, - uint32_t hash, uint16_t *curr, uint16_t *min, - uint16_t *max) -{ - if (ni->nat_action & NAT_ACTION_DST_PORT) { - *min = ni->min_port; - *max = ni->max_port; - *curr = *min + (hash % ((*max - *min) + 1)); - } else { - *curr = ntohs(k->dst.port); - *min = *max = *curr; - } -} - /* Gets the initial in range address based on the hash. * Addresses are kept in network order. */ static void @@ -2426,8 +2426,7 @@ nat_get_unique_tuple(struct conntrack *ct, const struct conn *conn, uint32_t hash = nat_range_hash(conn, ct->hash_basis, nat_info); bool pat_proto = conn->key.nw_proto == IPPROTO_TCP || conn->key.nw_proto == IPPROTO_UDP; - uint16_t min_dport, max_dport, curr_dport; - uint16_t min_sport, max_sport, curr_sport; + uint16_t min_port, max_port, curr_port; min_addr = nat_info->min_addr; max_addr = nat_info->max_addr; @@ -2439,10 +2438,8 @@ nat_get_unique_tuple(struct conntrack *ct, const struct conn *conn, * we can stop once we reach it. */ guard_addr = curr_addr; - set_sport_range(nat_info, &conn->key, hash, &curr_sport, - &min_sport, &max_sport); - set_dport_range(nat_info, &conn->key, hash, &curr_dport, - &min_dport, &max_dport); + set_port_range(nat_info, &conn->key, hash, &curr_port, + &min_port, &max_port); another_round: store_addr_to_key(&curr_addr, &nat_conn->rev_key, @@ -2457,14 +2454,14 @@ another_round: goto next_addr; } - FOR_EACH_PORT_IN_RANGE(curr_dport, min_dport, max_dport) { - nat_conn->rev_key.src.port = htons(curr_dport); - FOR_EACH_PORT_IN_RANGE(curr_sport, min_sport, max_sport) { - nat_conn->rev_key.dst.port = htons(curr_sport); - if (!conn_lookup(ct, &nat_conn->rev_key, - time_msec(), NULL, NULL)) { - return true; - } + FOR_EACH_PORT_IN_RANGE(curr_port, min_port, max_port) { + if (nat_info->nat_action & NAT_ACTION_SRC) { + nat_conn->rev_key.dst.port = htons(curr_port); + } else { + nat_conn->rev_key.src.port = htons(curr_port); + } + if (!conn_lookup(ct, &nat_conn->rev_key, time_msec(), NULL, NULL)) { + return true; } }