get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.1/patches/2220998/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2220998,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2220998/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260408163512.30537-8-fw@strlen.de/",
    "project": {
        "id": 26,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/26/?format=api",
        "name": "Netfilter Development",
        "link_name": "netfilter-devel",
        "list_id": "netfilter-devel.vger.kernel.org",
        "list_email": "netfilter-devel@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null
    },
    "msgid": "<20260408163512.30537-8-fw@strlen.de>",
    "date": "2026-04-08T16:35:12",
    "name": "[net,7/7] selftests: nft_queue.sh: add a parallel stress test",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "34736c12839cc36f0e854977843a763c699d4ea0",
    "submitter": {
        "id": 1025,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/1025/?format=api",
        "name": "Florian Westphal",
        "email": "fw@strlen.de"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260408163512.30537-8-fw@strlen.de/mbox/",
    "series": [
        {
            "id": 499159,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/499159/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/list/?series=499159",
            "date": "2026-04-08T16:35:05",
            "name": "[net,1/7] ipvs: fix NULL deref in ip_vs_add_service error path",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/499159/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2220998/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2220998/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "\n <netfilter-devel+bounces-11745-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "netfilter-devel@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-11745-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=91.216.245.30",
            "smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=strlen.de",
            "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=Chamillionaire.breakpoint.cc"
        ],
        "Received": [
            "from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frTL53x2kz1xv0\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 09 Apr 2026 02:39:25 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 24A40307D8F9\n\tfor <incoming@patchwork.ozlabs.org>; Wed,  8 Apr 2026 16:35:50 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 160493D1CC5;\n\tWed,  8 Apr 2026 16:35:49 +0000 (UTC)",
            "from Chamillionaire.breakpoint.cc (Chamillionaire.breakpoint.cc\n [91.216.245.30])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B8793B27CA;\n\tWed,  8 Apr 2026 16:35:47 +0000 (UTC)",
            "by Chamillionaire.breakpoint.cc (Postfix, from userid 1003)\n\tid B5D7460560; Wed, 08 Apr 2026 18:35:45 +0200 (CEST)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775666148; cv=none;\n b=LVTskgK0kVhbc13mY4Mw0xDdX9WZyJbxwZK74msq+Jh5NU8uifh2qYC7/YEtN9U71uG+P8BnTbzL0Pv3zx17A88wdgu/ZU4c45OZY0Tk6vpAvQWgRx1k9CDth0b0SXFYp6gaIG0es9hDyxDKYvEE9tny+uDp43FjMzZtlgY5bo0=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775666148; c=relaxed/simple;\n\tbh=+/rOeXhg1Ya6DR1P4O5XVmtQB/QwnQxKxP2BrEMvFko=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=ERePwnZqvn3UY2kEKT3t7WkEFu9oC7QBaT+SvLm0totqSwWPpr80DqxvDQPGGy+gUZU4mxt4U2dymrTuDTQ/5ftc0sxOAUu1Hm+xSHVJYaFb9Mi61eeUNvtp71jgnuKf9sfR19DA1nDXktdAfSN+ASJOtM+9hOdydHbIjneSKHg=",
        "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=strlen.de;\n spf=pass smtp.mailfrom=Chamillionaire.breakpoint.cc;\n arc=none smtp.client-ip=91.216.245.30",
        "From": "Florian Westphal <fw@strlen.de>",
        "To": "<netdev@vger.kernel.org>",
        "Cc": "Paolo Abeni <pabeni@redhat.com>,\n\t\"David S. Miller\" <davem@davemloft.net>,\n\tEric Dumazet <edumazet@google.com>,\n\tJakub Kicinski <kuba@kernel.org>,\n\t<netfilter-devel@vger.kernel.org>,\n\tpablo@netfilter.org",
        "Subject": "[PATCH net 7/7] selftests: nft_queue.sh: add a parallel stress test",
        "Date": "Wed,  8 Apr 2026 18:35:12 +0200",
        "Message-ID": "<20260408163512.30537-8-fw@strlen.de>",
        "X-Mailer": "git-send-email 2.52.0",
        "In-Reply-To": "<20260408163512.30537-1-fw@strlen.de>",
        "References": "<20260408163512.30537-1-fw@strlen.de>",
        "Precedence": "bulk",
        "X-Mailing-List": "netfilter-devel@vger.kernel.org",
        "List-Id": "<netfilter-devel.vger.kernel.org>",
        "List-Subscribe": "<mailto:netfilter-devel+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:netfilter-devel+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit"
    },
    "content": "From: Fernando Fernandez Mancera <fmancera@suse.de>\n\nIntroduce a new stress test to check for race conditions in the\nnfnetlink_queue subsystem, where an entry is freed while another CPU is\nconcurrently walking the global rhashtable.\n\nTo trigger this, `nf_queue.c` is extended with two new flags:\n  * -O (out-of-order): Buffers packet IDs and flushes them in reverse.\n  * -b (bogus verdicts): Floods the kernel with non-existent packet IDs.\n\nThe bogus verdict loop forces the kernel's lookup function to perform\nfull rhashtable bucket traversals (-ENOENT). Combined with reverse-order\nflushing and heavy parallel UDP/ping flooding across 8 queues, this puts\nthe nfnetlink_queue code under pressure.\n\nJoint work with Florian Westphal.\n\nSigned-off-by: Fernando Fernandez Mancera <fmancera@suse.de>\nSigned-off-by: Florian Westphal <fw@strlen.de>\n---\n .../selftests/net/netfilter/nf_queue.c        | 50 +++++++++--\n .../selftests/net/netfilter/nft_queue.sh      | 83 ++++++++++++++++---\n 2 files changed, 115 insertions(+), 18 deletions(-)",
    "diff": "diff --git a/tools/testing/selftests/net/netfilter/nf_queue.c b/tools/testing/selftests/net/netfilter/nf_queue.c\nindex 116c0ca0eabb..8bbec37f5356 100644\n--- a/tools/testing/selftests/net/netfilter/nf_queue.c\n+++ b/tools/testing/selftests/net/netfilter/nf_queue.c\n@@ -19,6 +19,8 @@ struct options {\n \tbool count_packets;\n \tbool gso_enabled;\n \tbool failopen;\n+\tbool out_of_order;\n+\tbool bogus_verdict;\n \tint verbose;\n \tunsigned int queue_num;\n \tunsigned int timeout;\n@@ -31,7 +33,7 @@ static struct options opts;\n \n static void help(const char *p)\n {\n-\tprintf(\"Usage: %s [-c|-v [-vv] ] [-o] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\\n\", p);\n+\tprintf(\"Usage: %s [-c|-v [-vv] ] [-o] [-O] [-b] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\\n\", p);\n }\n \n static int parse_attr_cb(const struct nlattr *attr, void *data)\n@@ -275,7 +277,9 @@ static int mainloop(void)\n \tunsigned int buflen = 64 * 1024 + MNL_SOCKET_BUFFER_SIZE;\n \tstruct mnl_socket *nl;\n \tstruct nlmsghdr *nlh;\n+\tuint32_t ooo_ids[16];\n \tunsigned int portid;\n+\tint ooo_count = 0;\n \tchar *buf;\n \tint ret;\n \n@@ -308,6 +312,9 @@ static int mainloop(void)\n \n \t\tret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);\n \t\tif (ret < 0) {\n+\t\t\t/* bogus verdict mode will generate ENOENT error messages */\n+\t\t\tif (opts.bogus_verdict && errno == ENOENT)\n+\t\t\t\tcontinue;\n \t\t\tperror(\"mnl_cb_run\");\n \t\t\texit(EXIT_FAILURE);\n \t\t}\n@@ -316,10 +323,35 @@ static int mainloop(void)\n \t\tif (opts.delay_ms)\n \t\t\tsleep_ms(opts.delay_ms);\n \n-\t\tnlh = nfq_build_verdict(buf, id, opts.queue_num, opts.verdict);\n-\t\tif (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {\n-\t\t\tperror(\"mnl_socket_sendto\");\n-\t\t\texit(EXIT_FAILURE);\n+\t\tif (opts.bogus_verdict) {\n+\t\t\tfor (int i = 0; i < 50; i++) {\n+\t\t\t\tnlh = nfq_build_verdict(buf, id + 0x7FFFFFFF + i,\n+\t\t\t\t\t\t\topts.queue_num, opts.verdict);\n+\t\t\t\tmnl_socket_sendto(nl, nlh, nlh->nlmsg_len);\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (opts.out_of_order) {\n+\t\t\tooo_ids[ooo_count] = id;\n+\t\t\tif (ooo_count >= 15) {\n+\t\t\t\tfor (ooo_count; ooo_count >= 0; ooo_count--) {\n+\t\t\t\t\tnlh = nfq_build_verdict(buf, ooo_ids[ooo_count],\n+\t\t\t\t\t\t\t\topts.queue_num, opts.verdict);\n+\t\t\t\t\tif (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {\n+\t\t\t\t\t\tperror(\"mnl_socket_sendto\");\n+\t\t\t\t\t\texit(EXIT_FAILURE);\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\tooo_count = 0;\n+\t\t\t} else {\n+\t\t\t\tooo_count++;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tnlh = nfq_build_verdict(buf, id, opts.queue_num, opts.verdict);\n+\t\t\tif (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {\n+\t\t\t\tperror(\"mnl_socket_sendto\");\n+\t\t\t\texit(EXIT_FAILURE);\n+\t\t\t}\n \t\t}\n \t}\n \n@@ -332,7 +364,7 @@ static void parse_opts(int argc, char **argv)\n {\n \tint c;\n \n-\twhile ((c = getopt(argc, argv, \"chvot:q:Q:d:G\")) != -1) {\n+\twhile ((c = getopt(argc, argv, \"chvoObt:q:Q:d:G\")) != -1) {\n \t\tswitch (c) {\n \t\tcase 'c':\n \t\t\topts.count_packets = true;\n@@ -375,6 +407,12 @@ static void parse_opts(int argc, char **argv)\n \t\tcase 'v':\n \t\t\topts.verbose++;\n \t\t\tbreak;\n+\t\tcase 'O':\n+\t\t\topts.out_of_order = true;\n+\t\t\tbreak;\n+\t\tcase 'b':\n+\t\t\topts.bogus_verdict = true;\n+\t\t\tbreak;\n \t\t}\n \t}\n \ndiff --git a/tools/testing/selftests/net/netfilter/nft_queue.sh b/tools/testing/selftests/net/netfilter/nft_queue.sh\nindex ea766bdc5d04..d80390848e85 100755\n--- a/tools/testing/selftests/net/netfilter/nft_queue.sh\n+++ b/tools/testing/selftests/net/netfilter/nft_queue.sh\n@@ -11,6 +11,7 @@ ret=0\n timeout=5\n \n SCTP_TEST_TIMEOUT=60\n+STRESS_TEST_TIMEOUT=30\n \n cleanup()\n {\n@@ -719,6 +720,74 @@ EOF\n \tfi\n }\n \n+check_tainted()\n+{\n+\tlocal msg=\"$1\"\n+\n+\tif [ \"$tainted_then\" -ne 0 ];then\n+\t\treturn\n+\tfi\n+\n+\tread tainted_now < /proc/sys/kernel/tainted\n+\tif [ \"$tainted_now\" -eq 0 ];then\n+\t\techo \"PASS: $msg\"\n+\telse\n+\t\techo \"TAINT: $msg\"\n+\t\tdmesg\n+\t\tret=1\n+\tfi\n+}\n+\n+test_queue_stress()\n+{\n+\tread tainted_then < /proc/sys/kernel/tainted\n+\tlocal i\n+\n+        ip netns exec \"$nsrouter\" nft -f /dev/stdin <<EOF\n+flush ruleset\n+table inet t {\n+\tchain forward {\n+\t\ttype filter hook forward priority 0; policy accept;\n+\n+\t\tqueue flags bypass to numgen random mod 8\n+\t}\n+}\n+EOF\n+\ttimeout \"$STRESS_TEST_TIMEOUT\" ip netns exec \"$ns2\" \\\n+\t\tsocat -u UDP-LISTEN:12345,fork,pf=ipv4 STDOUT > /dev/null &\n+\n+\ttimeout \"$STRESS_TEST_TIMEOUT\" ip netns exec \"$ns3\" \\\n+\t\tsocat -u UDP-LISTEN:12345,fork,pf=ipv4 STDOUT > /dev/null &\n+\n+\tfor i in $(seq 0 7); do\n+\t\tip netns exec \"$nsrouter\" timeout \"$STRESS_TEST_TIMEOUT\" \\\n+\t\t\t./nf_queue -q $i -t 2 -O -b > /dev/null &\n+\tdone\n+\n+\tip netns exec \"$ns1\" timeout \"$STRESS_TEST_TIMEOUT\" \\\n+\t\tping -q -f 10.0.2.99 > /dev/null 2>&1 &\n+\tip netns exec \"$ns1\" timeout \"$STRESS_TEST_TIMEOUT\" \\\n+\t\tping -q -f 10.0.3.99 > /dev/null 2>&1 &\n+\tip netns exec \"$ns1\" timeout \"$STRESS_TEST_TIMEOUT\" \\\n+\t\tping -q -f \"dead:2::99\" > /dev/null 2>&1 &\n+\tip netns exec \"$ns1\" timeout \"$STRESS_TEST_TIMEOUT\" \\\n+\t\tping -q -f \"dead:3::99\" > /dev/null 2>&1 &\n+\n+\tbusywait \"$BUSYWAIT_TIMEOUT\" udp_listener_ready \"$ns2\" 12345\n+\tbusywait \"$BUSYWAIT_TIMEOUT\" udp_listener_ready \"$ns3\" 12345\n+\n+\tfor i in $(seq 1 4);do\n+\t\tip netns exec \"$ns1\" timeout \"$STRESS_TEST_TIMEOUT\" \\\n+\t\t\tsocat -u STDIN UDP-DATAGRAM:10.0.2.99:12345 < /dev/zero > /dev/null &\n+\t\tip netns exec \"$ns1\" timeout \"$STRESS_TEST_TIMEOUT\" \\\n+\t\t\tsocat -u STDIN UDP-DATAGRAM:10.0.3.99:12345 < /dev/zero > /dev/null &\n+\tdone\n+\n+\twait\n+\n+\tcheck_tainted \"concurrent queueing\"\n+}\n+\n test_queue_removal()\n {\n \tread tainted_then < /proc/sys/kernel/tainted\n@@ -742,18 +811,7 @@ EOF\n \n \tip netns exec \"$ns1\" nft flush ruleset\n \n-\tif [ \"$tainted_then\" -ne 0 ];then\n-\t\treturn\n-\tfi\n-\n-\tread tainted_now < /proc/sys/kernel/tainted\n-\tif [ \"$tainted_now\" -eq 0 ];then\n-\t\techo \"PASS: queue program exiting while packets queued\"\n-\telse\n-\t\techo \"TAINT: queue program exiting while packets queued\"\n-\t\tdmesg\n-\t\tret=1\n-\tfi\n+\tcheck_tainted \"queue program exiting while packets queued\"\n }\n \n ip netns exec \"$nsrouter\" sysctl net.ipv6.conf.all.forwarding=1 > /dev/null\n@@ -799,6 +857,7 @@ test_sctp_forward\n test_sctp_output\n test_udp_nat_race\n test_udp_gro_ct\n+test_queue_stress\n \n # should be last, adds vrf device in ns1 and changes routes\n test_icmp_vrf\n",
    "prefixes": [
        "net",
        "7/7"
    ]
}