get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/1526073/
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1526073,
    "url": "http://patchwork.ozlabs.org/api/patches/1526073/",
    "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/1631156814-12127-3-git-send-email-wenxu@ucloud.cn/",
    "project": {
        "id": 47,
        "url": "http://patchwork.ozlabs.org/api/projects/47/",
        "name": "Open vSwitch",
        "link_name": "openvswitch",
        "list_id": "ovs-dev.openvswitch.org",
        "list_email": "ovs-dev@openvswitch.org",
        "web_url": "http://openvswitch.org/",
        "scm_url": "git@github.com:openvswitch/ovs.git",
        "webscm_url": "https://github.com/openvswitch/ovs",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1631156814-12127-3-git-send-email-wenxu@ucloud.cn>",
    "list_archive_url": null,
    "date": "2021-09-09T03:06:54",
    "name": "[ovs-dev,v4,3/3] conntrack: limit port clash resolution attempts",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "89fdafed87e22abb3bbec077ac317f56d61429ad",
    "submitter": {
        "id": 67928,
        "url": "http://patchwork.ozlabs.org/api/people/67928/",
        "name": "wenxu",
        "email": "wenxu@ucloud.cn"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/1631156814-12127-3-git-send-email-wenxu@ucloud.cn/mbox/",
    "series": [
        {
            "id": 261540,
            "url": "http://patchwork.ozlabs.org/api/series/261540/",
            "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=261540",
            "date": "2021-09-09T03:06:52",
            "name": "[ovs-dev,v4,1/3] conntrack: restore the origin sport for each round with new address",
            "version": 4,
            "mbox": "http://patchwork.ozlabs.org/series/261540/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/1526073/comments/",
    "check": "success",
    "checks": "http://patchwork.ozlabs.org/api/patches/1526073/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<ovs-dev-bounces@openvswitch.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "dev@openvswitch.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "ovs-dev@lists.linuxfoundation.org"
        ],
        "Authentication-Results": "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=140.211.166.133; helo=smtp2.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN>)",
        "Received": [
            "from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4H4kSl0P0Jz9t0k\n\tfor <incoming@patchwork.ozlabs.org>; Thu,  9 Sep 2021 13:07:19 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp2.osuosl.org (Postfix) with ESMTP id EC1B84071E;\n\tThu,  9 Sep 2021 03:07:12 +0000 (UTC)",
            "from smtp2.osuosl.org ([127.0.0.1])\n\tby localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id ZBnD259w7QmQ; Thu,  9 Sep 2021 03:07:11 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp2.osuosl.org (Postfix) with ESMTPS id A475640708;\n\tThu,  9 Sep 2021 03:07:05 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id EA6FEC0024;\n\tThu,  9 Sep 2021 03:07:03 +0000 (UTC)",
            "from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 37F2BC000D\n for <dev@openvswitch.org>; Thu,  9 Sep 2021 03:07:02 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 1B5FA830CD\n for <dev@openvswitch.org>; Thu,  9 Sep 2021 03:07:02 +0000 (UTC)",
            "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n with ESMTP id p2GvVI9BD_-s for <dev@openvswitch.org>;\n Thu,  9 Sep 2021 03:07:01 +0000 (UTC)",
            "from mail-m2456.qiye.163.com (mail-m2456.qiye.163.com\n [220.194.24.56])\n by smtp1.osuosl.org (Postfix) with ESMTPS id 3D9CB82F11\n for <dev@openvswitch.org>; Thu,  9 Sep 2021 03:07:01 +0000 (UTC)",
            "from localhost.localdomain (unknown [117.50.0.204])\n by mail-m2456.qiye.163.com (Hmail) with ESMTPA id 7773670023C;\n Thu,  9 Sep 2021 11:06:55 +0800 (CST)"
        ],
        "X-Virus-Scanned": [
            "amavisd-new at osuosl.org",
            "amavisd-new at osuosl.org"
        ],
        "X-Greylist": "domain auto-whitelisted by SQLgrey-1.8.0",
        "From": "wenxu@ucloud.cn",
        "To": "pvalerio@redhat.com,\n\taconole@redhat.com",
        "Date": "Thu,  9 Sep 2021 11:06:54 +0800",
        "Message-Id": "<1631156814-12127-3-git-send-email-wenxu@ucloud.cn>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1631156814-12127-1-git-send-email-wenxu@ucloud.cn>",
        "References": "<1631156814-12127-1-git-send-email-wenxu@ucloud.cn>",
        "X-HM-Spam-Status": "e1kfGhgUHx5ZQUtXWQgPGg8OCBgUHx5ZQUlOS1dZCBgUCR5ZQVlLVUtZV1\n kWDxoPAgseWUFZKDYvK1lXWShZQUlCN1dZLVlBSVdZDwkaFQgSH1lBWUMYQ0lWQxhLTEtDHxkeTx\n pLVRkRExYaEhckFA4PWVdZFhoPEhUdFFlBWVVLWQY+",
        "X-HM-Sender-Digest": "e1kMHhlZQR0aFwgeV1kSHx4VD1lBWUc6MyI6TTo5PDNCPxQxT0JRCx0i\n Qh8KCR5VSlVKTUhKSk5NQ0pOTExNVTMWGhIXVQweFQMOOw4YFxQOH1UYFUVZV1kSC1lBWUpKTFVO\n S1VLVUlLT1lXWQgBWUFPT0NLNwY+",
        "X-HM-Tid": "0a7bc885c6948c15kuqt7773670023c",
        "Cc": "dev@openvswitch.org, i.maximets@ovn.org",
        "Subject": "[ovs-dev] [PATCH v4 3/3] conntrack: limit port clash resolution\n\tattempts",
        "X-BeenThere": "ovs-dev@openvswitch.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "<ovs-dev.openvswitch.org>",
        "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>",
        "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>",
        "List-Post": "<mailto:ovs-dev@openvswitch.org>",
        "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>",
        "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "ovs-dev-bounces@openvswitch.org",
        "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>"
    },
    "content": "From: wenxu <wenxu@ucloud.cn>\n\nIn case almost or all available ports are taken, clash resolution can\ntake a very long time, resulting in pmd hang in conntrack.\n\nThis can happen when many to-be-natted hosts connect to same\ndestination:port (e.g. a proxy) and all connections pass the same SNAT.\n\nPick a random offset in the acceptable range, then try ever smaller\nnumber of adjacent port numbers, until either the limit is reached or a\nuseable port was found.  This results in at most 248 attempts\n(128 + 64 + 32 + 16 + 8, i.e. 4 restarts with new search offset)\ninstead of 64000+.\n\nSigned-off-by: wenxu <wenxu@ucloud.cn>\n---\n lib/conntrack.c | 47 +++++++++++++++++++++++++++++++++++++++++++----\n 1 file changed, 43 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/lib/conntrack.c b/lib/conntrack.c\nindex f95532c..485b31c 100644\n--- a/lib/conntrack.c\n+++ b/lib/conntrack.c\n@@ -2421,7 +2421,11 @@ nat_get_unique_tuple(struct conntrack *ct, const struct conn *conn,\n     uint32_t hash = nat_range_hash(conn, ct->hash_basis);\n     bool pat_proto = conn->key.nw_proto == IPPROTO_TCP ||\n                      conn->key.nw_proto == IPPROTO_UDP;\n+    unsigned int attempts, max_attempts, min_attempts;\n     uint16_t min_dport, max_dport, curr_dport;\n+    uint16_t range_src, range_dst, range_max;\n+    uint32_t range_addr;\n+    unsigned int i;\n \n     min_addr = conn->nat_info->min_addr;\n     max_addr = conn->nat_info->max_addr;\n@@ -2438,6 +2442,19 @@ nat_get_unique_tuple(struct conntrack *ct, const struct conn *conn,\n     set_dport_range(conn->nat_info, &conn->key, hash, &curr_dport,\n                     &min_dport, &max_dport);\n \n+    range_src = max_sport - min_sport + 1;\n+    range_dst = max_dport - min_dport + 1;\n+    range_max = range_src > range_dst ? range_src : range_dst;\n+    range_addr = ntohl(max_addr.ipv4) - ntohl(min_addr.ipv4) + 1;\n+    max_attempts = 128 / range_addr;\n+    if (max_attempts < 1) {\n+        max_attempts = 1;\n+    }\n+    min_attempts = 16 / range_addr;\n+    if (min_attempts < 2) {\n+        min_attempts = 2;\n+    }\n+\n another_round:\n     store_addr_to_key(&curr_addr, &nat_conn->rev_key,\n                       conn->nat_info->nat_action);\n@@ -2453,17 +2470,39 @@ another_round:\n \n     curr_sport = orig_sport;\n \n+    attempts = range_max;\n+    if (attempts > max_attempts) {\n+        attempts = max_attempts;\n+    }\n+\n+another_port_round:\n+    i = 0;\n     FOR_EACH_PORT_IN_RANGE(curr_dport, min_dport, max_dport) {\n         nat_conn->rev_key.src.port = htons(curr_dport);\n         FOR_EACH_PORT_IN_RANGE(curr_sport, min_sport, max_sport) {\n-            nat_conn->rev_key.dst.port = htons(curr_sport);\n-            if (!conn_lookup(ct, &nat_conn->rev_key,\n-                             time_msec(), NULL, NULL)) {\n-                return true;\n+            if (i++ < attempts) {\n+                nat_conn->rev_key.dst.port = htons(curr_sport);\n+                if (!conn_lookup(ct, &nat_conn->rev_key,\n+                                 time_msec(), NULL, NULL)) {\n+                    return true;\n+                }\n+            } else {\n+                goto next_attempts;\n             }\n         }\n     }\n \n+next_attempts:\n+    if (attempts >= range_max || attempts < min_attempts) {\n+        goto next_addr;\n+    }\n+\n+    attempts /= 2;\n+    curr_dport = min_dport + (random_uint32() % range_dst);\n+    curr_sport = min_sport + (random_uint32() % range_src);\n+\n+    goto another_port_round;\n+\n     /* Check if next IP is in range and respin. Otherwise, notify\n      * exhaustion to the caller. */\n next_addr:\n",
    "prefixes": [
        "ovs-dev",
        "v4",
        "3/3"
    ]
}