From nobody Thu Sep 24 17:02:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5353C3B27C6; Tue, 22 Sep 2026 02:55:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790045731; cv=none; b=YGSXzCob1x16Rf3YiYhCaiNQb5qWFtidkx3leDdPJMRAutY9gVGHPzums7YUDteDHcDSXEpyzekgpwgPK2+TUdsRZR59Zhylvtaii9GwV/EBfbTgnvlumL08lO313QPNzCCPavIh3NzY8QT4l4uhw85+wC2NYMBdM/Qnm6kd6Mk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790045731; c=relaxed/simple; bh=+7tk65VehXfxdW/hJz5YnXEKaDRQhunCVmEtXDvuLSg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=feJv52DMTdIWEzMx4vldAVcseC6Ld0zAHd8XnJnqeESoSoN70sJHZwDtLntBBv/3gYWVK73jiUlJvhCqQWH61W3e5ODdqD6tG7EaVvi/TjITkEulhxzfaEmCU0oRoo5HLflJ76QjIOKPVlij1jRbrmVhC9oWL5Jl02ho1dn+XCg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=KJ6+18KJ; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="KJ6+18KJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=vl kyJfsgylXlYUWQ2UWwJsTEdH4rKHN0ZElZoFLMfkg=; b=KJ6+18KJkW2LVVH234 PpZ4ACc+3fFo8HQupPsTz2+SjIysMgPn62KO/lxrjFIMFURFS/nzoZpIelakCuTD kOyw69RSxEzSB0gy5ki1ht/GdMpnzJ0sAb6PY+Sf8YZd85YoUa9rB6dPFZBVkosK pE28PRC+GNV/wugCu/J70fne8= Received: from localhost (unknown []) by gzsmtp5 (Coremail) with SMTP id QCgvCgCn8HP07bFqT6riAg--.6728S2; Tue, 22 Sep 2026 10:54:45 +0800 (CST) From: Hui Su To: bpf@vger.kernel.org, Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi Cc: Yonghong Song , Quentin Monnet , Martin KaFai Lau , Song Liu , Jiri Olsa , Emil Tsalapatis , Ihor Solodrai , Shuah Khan , linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Hui Su Subject: [PATCH bpf-next v3 1/3] bpf: Report BPF_F_PREORDER in cgroup program queries Date: Tue, 22 Sep 2026 11:54:40 +0900 Message-ID: <20260922025442.3176057-2-sh_def@163.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260922025442.3176057-1-sh_def@163.com> References: <20260922025442.3176057-1-sh_def@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: QCgvCgCn8HP07bFqT6riAg--.6728S2 X-Coremail-Antispam: 1Uf129KBjvJXoW7AF4xCryftw47JrWfZrW7CFg_yoW8Cw17pF s5XFW7K3Wjvryaqw40g34FvrW0g3Z3XF1UCF9xG34fuayagr18tr9akFW5CFy5trZxCr10 vF90vr4Ygr1jvF7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0zioq2tUUUUU= X-CM-SenderInfo: xvkbvvri6rljoofrz/xtbC6hW-H2qx7fXSfwAA3x Content-Type: text/plain; charset="utf-8" Extend direct cgroup program queries to merge (pl->flags & BPF_F_PREORDER) with the cgroup-wide flags when copying prog_attach_flags to user space. Only BPF_F_PREORDER is extracted from pl->flags to ensure transient positioning flags (such as BPF_F_BEFORE, BPF_F_AFTER, BPF_F_ID, or BPF_F_REPLACE) are not leaked to user space. This can introduce new prog_attach_flags[] values with BPF_F_PREORDER set, for example 0x40 (BPF_F_PREORDER), 0x41 (BPF_F_ALLOW_OVERRIDE | BPF_F_PREORDER), or 0x42 (BPF_F_ALLOW_MULTI | BPF_F_PREORDER), depending on the cgroup-wide attachment mode. Older bpftool versions treat such combinations as unknown flags; bpftool support is updated later in this series. Signed-off-by: Hui Su --- Notes (bpf-preorder-v3-20260922-check): Testing: - PASS: ./test_progs -t cgroup_mprog_opts (x86_64 QEMU/KVM). - Result reused after a content-equivalent rebase; the patch diff is un= changed. kernel/bpf/cgroup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 1cb5e6a6ffc1..2bbe77de89f0 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1515,19 +1515,19 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, = const union bpf_attr *attr, id =3D prog_list_id(pl); if (copy_to_user(prog_ids + i, &id, sizeof(id))) return -EFAULT; + if (prog_attach_flags) { + flags =3D cgrp->bpf.flags[atype] | + (pl->flags & BPF_F_PREORDER); + if (copy_to_user(prog_attach_flags + i, + &flags, sizeof(flags))) + return -EFAULT; + } if (++i =3D=3D cnt) break; } =20 - if (prog_attach_flags) { - flags =3D cgrp->bpf.flags[atype]; - - for (i =3D 0; i < cnt; i++) - if (copy_to_user(prog_attach_flags + i, - &flags, sizeof(flags))) - return -EFAULT; + if (prog_attach_flags) prog_attach_flags +=3D cnt; - } } =20 prog_ids +=3D cnt; --=20 2.55.0 From nobody Thu Sep 24 17:02:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 98E1B396B73; Tue, 22 Sep 2026 02:55:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790045730; cv=none; b=dCTdII2CELhmuBpJF6UN4gBkR2ScPxw3HVoUkbZ3sCGNqBJcb3st7/kUBLMa1Sj9BVq4XAtsIotwsDosijQ3xr+Tjkg9evkRKzaDHZPkZvGW5tacRg4A/w1R4hC8tzzxtrpaF/jHp0uwMXyh32XIM4J/x4IGhgjRsz+0wj61+TU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790045730; c=relaxed/simple; bh=0xzZVOhoypwAdF5+Xju08tZYyhoMjnoxCtlg3ugodOA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qmAMQOldst9GbFR8EDC8BsRouX0dHYcOipvu1pyO/I2ZlFhi4he5CYkfLVdIZBC+nsV5bgVVxOmsaLvpsO/IBbXl0n9ogoVWHWgZsxcvoWn95Ac1lwyy8Q5MQopH1ns5Txrv2HxFmm6NUAlfS8c/UdpeyU3TX/zNPYpCTPbc1Xk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=bytErMrh; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="bytErMrh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=cb 55GOKo+r5kxR5wVL0sF6MPAalrQ/xmn6/rb5ZTF6I=; b=bytErMrhSD0epy/Jkt pF9c5n+b5e+PWB+/czsKEt+vfp+wHVD35Ux5driXB7+UHFu1JZ/3ZSx2R7cJVIKm uVX6CHwmBPRyGA/Kcl97HpI0zHqrDuedwI9YnZ9DqGsaEggCFTP5Z7hlnA5v7eAg 3p/PatXV/CEfimwyM8UuZrh/s= Received: from localhost (unknown []) by gzga-smtp-mtada-g0-1 (Coremail) with SMTP id _____wDXf5f17bFqiWEXAA--.13164S2; Tue, 22 Sep 2026 10:54:46 +0800 (CST) From: Hui Su To: bpf@vger.kernel.org, Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi Cc: Yonghong Song , Quentin Monnet , Martin KaFai Lau , Song Liu , Jiri Olsa , Emil Tsalapatis , Ihor Solodrai , Shuah Khan , linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Hui Su Subject: [PATCH bpf-next v3 2/3] selftests/bpf: Test querying BPF_F_PREORDER cgroup attachments Date: Tue, 22 Sep 2026 11:54:41 +0900 Message-ID: <20260922025442.3176057-3-sh_def@163.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260922025442.3176057-1-sh_def@163.com> References: <20260922025442.3176057-1-sh_def@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wDXf5f17bFqiWEXAA--.13164S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxWw4xKFyfXw1UCw48Gw1DAwb_yoWrKF1xpF ykXFy7tF1rXa4UXa15t3y7Zr4avFn7X3W2kFWFgwn09FWDWFy09ry8KF4YyF1ft395Zw1I vwn0vrsxXr1DWF7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pi5CzJUUUUU= X-CM-SenderInfo: xvkbvvri6rljoofrz/xtbC6Ra-H2qx7fYr2gAA3u Content-Type: text/plain; charset="utf-8" Extend cgroup_mprog_opts selftests to verify that BPF_PROG_QUERY reports BPF_F_PREORDER in prog_attach_flags for both direct program and link attachments. Verify that: - Programs attached with BPF_F_PREORDER report BPF_F_ALLOW_MULTI | BPF_F_PREORDER (0x42) in prog_attach_flags. - Programs attached without BPF_F_PREORDER report BPF_F_ALLOW_MULTI (0x2). - Transient flags such as BPF_F_AFTER or BPF_F_LINK are not present in prog_attach_flags. Signed-off-by: Hui Su --- Notes (bpf-preorder-v3-20260922-check): Testing: - PASS: ./test_progs -t cgroup_preorder (x86_64 QEMU/KVM). - Result reused after a content-equivalent rebase; the patch diff is un= changed. .../bpf/prog_tests/cgroup_mprog_opts.c | 71 ++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/cgroup_mprog_opts.c b/t= ools/testing/selftests/bpf/prog_tests/cgroup_mprog_opts.c index bb60704a3ef9..9ec5e4f96312 100644 --- a/tools/testing/selftests/bpf/prog_tests/cgroup_mprog_opts.c +++ b/tools/testing/selftests/bpf/prog_tests/cgroup_mprog_opts.c @@ -273,11 +273,64 @@ static void test_link_attach_detach(int atype) close(cg); } =20 +static int find_prog_attach_flags(const struct bpf_prog_query_opts *opts, + __u32 prog_id, __u32 *flags) +{ + __u32 i; + + for (i =3D 0; i < opts->count; i++) { + if (opts->prog_ids[i] =3D=3D prog_id) { + *flags =3D opts->prog_attach_flags[i]; + return 0; + } + } + return -ENOENT; +} + +static void assert_preorder_query_flags(int cg, int atype, + __u32 id1, __u32 id2, + __u32 id3, __u32 id4) +{ + LIBBPF_OPTS(bpf_prog_query_opts, optq); + __u32 prog_attach_flags[10] =3D {}; + __u32 prog_ids[10] =3D {}; + __u32 flags; + int err; + + optq.prog_ids =3D prog_ids; + optq.prog_attach_flags =3D prog_attach_flags; + optq.count =3D 10; + err =3D bpf_prog_query_opts(cg, atype, &optq); + if (!ASSERT_OK(err, "prog_query")) + return; + + ASSERT_EQ(optq.count, 4, "count"); + + /* Match by prog_id to avoid relying on query order. */ + err =3D find_prog_attach_flags(&optq, id1, &flags); + if (ASSERT_OK(err, "find id1")) + ASSERT_EQ(flags, BPF_F_ALLOW_MULTI, "flags id1"); + + err =3D find_prog_attach_flags(&optq, id2, &flags); + if (ASSERT_OK(err, "find id2")) + ASSERT_EQ(flags, BPF_F_ALLOW_MULTI | BPF_F_PREORDER, + "flags id2"); + + err =3D find_prog_attach_flags(&optq, id3, &flags); + if (ASSERT_OK(err, "find id3")) + ASSERT_EQ(flags, BPF_F_ALLOW_MULTI | BPF_F_PREORDER, + "flags id3"); + + err =3D find_prog_attach_flags(&optq, id4, &flags); + if (ASSERT_OK(err, "find id4")) + ASSERT_EQ(flags, BPF_F_ALLOW_MULTI, "flags id4"); +} + static void test_preorder_prog_attach_detach(int atype) { LIBBPF_OPTS(bpf_prog_attach_opts, opta); LIBBPF_OPTS(bpf_prog_detach_opts, optd); - __u32 fd1, fd2, fd3, fd4; + __u32 fd1, fd2, fd3, fd4, id1, id2, id3, id4; struct cgroup_mprog *skel; int cg, err; =20 @@ -294,6 +347,11 @@ static void test_preorder_prog_attach_detach(int atype) fd3 =3D bpf_program__fd(skel->progs.getsockopt_3); fd4 =3D bpf_program__fd(skel->progs.getsockopt_4); =20 + id1 =3D id_from_prog_fd(fd1); + id2 =3D id_from_prog_fd(fd2); + id3 =3D id_from_prog_fd(fd3); + id4 =3D id_from_prog_fd(fd4); + assert_mprog_count(cg, atype, 0); =20 LIBBPF_OPTS_RESET(opta, @@ -357,6 +415,8 @@ static void test_preorder_prog_attach_detach(int atype) =20 assert_mprog_count(cg, atype, 4); =20 + assert_preorder_query_flags(cg, atype, id1, id2, id3, id4); + err =3D bpf_prog_detach_opts(fd4, cg, atype, &optd); ASSERT_OK(err, "prog_detach"); assert_mprog_count(cg, atype, 3); @@ -386,7 +446,7 @@ static void test_preorder_link_attach_detach(int atype) LIBBPF_OPTS(bpf_cgroup_opts, opta); struct bpf_link *link1, *link2, *link3, *link4; struct cgroup_mprog *skel; - __u32 fd2; + __u32 fd2, id1, id2, id3, id4; int cg; =20 cg =3D test__join_cgroup("/preorder_link_attach_detach"); @@ -399,6 +459,11 @@ static void test_preorder_link_attach_detach(int atype) =20 fd2 =3D bpf_program__fd(skel->progs.getsockopt_2); =20 + id1 =3D id_from_prog_fd(bpf_program__fd(skel->progs.getsockopt_1)); + id2 =3D id_from_prog_fd(fd2); + id3 =3D id_from_prog_fd(bpf_program__fd(skel->progs.getsockopt_3)); + id4 =3D id_from_prog_fd(bpf_program__fd(skel->progs.getsockopt_4)); + assert_mprog_count(cg, atype, 0); =20 LIBBPF_OPTS_RESET(opta, @@ -460,6 +525,8 @@ static void test_preorder_link_attach_detach(int atype) =20 assert_mprog_count(cg, atype, 4); =20 + assert_preorder_query_flags(cg, atype, id1, id2, id3, id4); + bpf_link__destroy(link4); assert_mprog_count(cg, atype, 3); =20 --=20 2.55.0 From nobody Thu Sep 24 17:02:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 344ED3403E8; Tue, 22 Sep 2026 02:55:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790045730; cv=none; b=IuIVxt8LmXhmbwJQraLOYTWD/BD1etKQibSSjf9HSMGbQEWivPQ0ZlaNps8BMTl97LPnFB/4L6bARJ6D+mH6qvvxiAjbYcs02OendXc4D4NmFZr4mK4BlGlgrYETxx96P1NLbz8FMmSo9vVkswpfYcYwK+UUb0kus771wA4X4yg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790045730; c=relaxed/simple; bh=hK7dnz1fNm88X0+jYTY2ejo9vM/95ELnAQpFUBTeMt8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=a0zN5ZVnHtBQl9QBwrlatoBd9nprwCutJhgL6tf2dAogPUWCT/z29tGvvGxCSG90Ypq8v9u3NTJex6gs7eh6mUtZ/vZZxMeLkMimAXcaAKJexbcMCx6xtS5M5Pvhao/PXefMPhbWth/1goNrS1pWT8XLogSidf8GScEXJ4awPEM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=J4Aphnuh; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="J4Aphnuh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=ec P5t7ttauiOdWWIApxVQOiSA4P1UHFyxmZ+YpcJYfc=; b=J4AphnuhfyBUSRdBLC ynguUWmRdK1MFqgGH5eEYYcKAFpDhh1c5gWGhSOL36uXJFHpHJjxrd+kCGsGkabf m4s65EGHSoIfOozGJoJia+6GPYEh3rlCFUt6aeaDY9GFtQElEoLj2qSL8uGk2RFR /B7SgK/EGj1MZtu1190g6k7Lg= Received: from localhost (unknown []) by gzsmtp5 (Coremail) with SMTP id QCgvCgB3DGn27bFqwKviAg--.7291S2; Tue, 22 Sep 2026 10:54:47 +0800 (CST) From: Hui Su To: bpf@vger.kernel.org, Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Eduard Zingerman , Kumar Kartikeya Dwivedi Cc: Yonghong Song , Quentin Monnet , Martin KaFai Lau , Song Liu , Jiri Olsa , Emil Tsalapatis , Ihor Solodrai , Shuah Khan , linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Hui Su Subject: [PATCH bpf-next v3 3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag Date: Tue, 22 Sep 2026 11:54:42 +0900 Message-ID: <20260922025442.3176057-4-sh_def@163.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260922025442.3176057-1-sh_def@163.com> References: <20260922025442.3176057-1-sh_def@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: QCgvCgB3DGn27bFqwKviAg--.7291S2 X-Coremail-Antispam: 1Uf129KBjvJXoW3Cw4kJr4DCw4DAryfKr13CFg_yoWkGw1DpF 4kXa4jk3W8W3sxWw48G3yYgrWrKrs7WF1UCF98Jry5uFW3Ww1vyrWSkFWrurn8XFWxAw40 vF4Yvr15WF1jvFDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pi5CzJUUUUU= X-CM-SenderInfo: xvkbvvri6rljoofrz/xtbCwhe-H2qx7feniAAA3b Content-Type: text/plain; charset="utf-8" Commit 4b82b181a26c ("bpf: Allow pre-ordering for bpf cgroup progs") introduced BPF_F_PREORDER to request pre-order execution across the cgroup hierarchy. Furthermore, attachments legitimately use combinations such as BPF_F_ALLOW_MULTI | BPF_F_PREORDER or BPF_F_ALLOW_OVERRIDE | BPF_F_PREORDER. With BPF_PROG_QUERY reporting the per-program BPF_F_PREORDER attribute, bpftool's exact-match formatter falls back to "unknown(40)" when BPF_F_PREORDER is present alone, or "unknown(41)" / "unknown(42)" when combined with BPF_F_ALLOW_OVERRIDE or BPF_F_ALLOW_MULTI. Additionally, do_attach() only accepts "multi" and "override", rejecting "preorder" with "unknown option". Before: $ bpftool cgroup show 1234 cgroup_inet_ingress unknown(42) test_prog $ bpftool cgroup attach cgroup_inet_ingress id 5678 multi preorder Error: unknown option: preorder After: $ bpftool cgroup show 1234 cgroup_inet_ingress multi,preorder test_prog $ bpftool cgroup attach cgroup_inet_ingress id 5678 multi preorder (attaches successfully) Refactor the attach flags formatter into a bitmask formatter that outputs comma-separated flag names for plain text while preserving unrecognized bits as "unknown(...)". Render attach flags as an array of flag names in JSON output. Accept "preorder" in do_attach(), update the cgroup documentation and synopsis to express valid flag combinations, and teach bash completion about them ("multi" or "override" optionally combined with "preorder"). Signed-off-by: Hui Su Acked-by: Quentin Monnet --- Notes (bpf-preorder-v3-20260922-check): Testing: - PASS: make -C tools/bpf/bpftool -j12 (fresh after rebase). - PASS: make -C tools/bpf/bpftool/Documentation -j12 (fresh after rebas= e). - PASS: bash -n tools/bpf/bpftool/bash-completion/bpftool (fresh after = rebase). - PASS: bpftool cgroup plain-text and JSON runtime smoke (x86_64 QEMU/K= VM); result reused after a content-equivalent rebase. - PASS: scripts/checkpatch.pl on the generated v3 patches. .../bpftool/Documentation/bpftool-cgroup.rst | 25 +++-- tools/bpf/bpftool/bash-completion/bpftool | 4 +- tools/bpf/bpftool/cgroup.c | 99 +++++++++++++------ 3 files changed, 89 insertions(+), 39 deletions(-) diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf= /bpftool/Documentation/bpftool-cgroup.rst index e8185596a759..d1b8193dc576 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst @@ -45,7 +45,7 @@ CGROUP COMMANDS | **cgroup_unix_recvmsg** | **cgroup_sysctl** | | **cgroup_getsockopt** | **cgroup_setsockopt** | | **cgroup_inet_sock_release** } -| *ATTACH_FLAGS* :=3D { **multi** | **override** } +| *ATTACH_FLAGS* :=3D { [ **multi** | **override** ] [ **preorder** ] } =20 DESCRIPTION =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -75,20 +75,27 @@ bpftool cgroup attach *CGROUP* *ATTACH_TYPE* *PROG* [*A= TTACH_FLAGS*] Attach program *PROG* to the cgroup *CGROUP* with attach type *ATTACH_= TYPE* and optional *ATTACH_FLAGS*. =20 - *ATTACH_FLAGS* can be one of: **override** if a sub-cgroup installs so= me + *ATTACH_FLAGS* can include: **override** if a sub-cgroup installs some bpf program, the program in this cgroup yields to sub-cgroup program; **multi** if a sub-cgroup installs some bpf program, that cgroup progr= am - gets run in addition to the program in this cgroup. + gets run in addition to the program in this cgroup; + **preorder** requests ancestor-to-descendant execution for this progra= m, + before non-preorder programs, which execute descendants-to-ancestors + across the cgroup hierarchy. Note that **preorder** alone does not ena= ble + multi-program attachment; specify **multi** together with **preorder**= to + attach multiple programs. =20 - Only one program is allowed to be attached to a cgroup with no attach = flags - or the **override** flag. Attaching another program will release old - program and attach the new one. + Only one program is allowed to be attached to a cgroup unless the + **multi** flag is specified. Without **multi**, attaching another prog= ram + replaces the existing program, provided the **override** setting match= es. =20 Multiple programs are allowed to be attached to a cgroup with **multi*= *. - They are executed in FIFO order (those that were attached first, run - first). + Programs marked with **preorder** are placed before non-preorder progr= ams + in the effective program array. Within each ordering class at the same + cgroup level, attachment order is preserved. =20 - Non-default *ATTACH_FLAGS* are supported by kernel version 4.14 and la= ter. + **multi** and **override** are supported by kernel version 4.14 and la= ter. + **preorder** was introduced upstream in Linux 6.15. =20 *ATTACH_TYPE* can be one of: =20 diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/= bash-completion/bpftool index c9e8761e4ef2..9d9ced270685 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -1064,7 +1064,6 @@ _bpftool() attach|detach) local BPFTOOL_CGROUP_ATTACH_TYPES=3D"$(bpftool feature= list_builtins attach_types 2>/dev/null | \ grep '^cgroup_')" - local ATTACH_FLAGS=3D'multi override' # Check for $prev =3D $command first if [ $prev =3D $command ]; then _filedir @@ -1094,7 +1093,8 @@ _bpftool() # "id|pinned|tag|name" (we already checked= for # that). This should only leave the case w= hen # we need attach flags for "attach" commam= nd. - _bpftool_one_of_list "$ATTACH_FLAGS" + _bpftool_one_of_list 'multi override' + _bpftool_once_attr 'preorder' fi return 0 ;; diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c index ce69d1e5468e..fee1a260f6d1 100644 --- a/tools/bpf/bpftool/cgroup.c +++ b/tools/bpf/bpftool/cgroup.c @@ -56,7 +56,7 @@ static const int cgroup_attach_types[] =3D { }; =20 #define HELP_SPEC_ATTACH_FLAGS \ - "ATTACH_FLAGS :=3D { multi | override }" + "ATTACH_FLAGS :=3D { [ multi | override ] [ preorder ] }" =20 #define HELP_SPEC_ATTACH_TYPES \ " ATTACH_TYPE :=3D { cgroup_inet_ingress | cgroup_inet_egress |\n" \ @@ -138,11 +138,69 @@ static void guess_vmlinux_btf_id(__u32 attach_btf_obj= _id) close(fd); } =20 +static const struct { + __u32 flag; + const char *name; +} attach_flag_names[] =3D { + { BPF_F_ALLOW_MULTI, "multi" }, + { BPF_F_ALLOW_OVERRIDE, "override" }, + { BPF_F_PREORDER, "preorder" }, +}; + +static const char *format_attach_flags(__u32 flags, char *buf, size_t sz) +{ + size_t len =3D 0; + size_t i; + int n; + + buf[0] =3D '\0'; + for (i =3D 0; i < ARRAY_SIZE(attach_flag_names); i++) { + if (flags & attach_flag_names[i].flag) { + n =3D snprintf(buf + len, sz - len, "%s%s", + len ? "," : "", attach_flag_names[i].name); + if (n < 0 || (size_t)n >=3D sz - len) + return buf; + len +=3D n; + flags &=3D ~attach_flag_names[i].flag; + } + } + + if (flags) + snprintf(buf + len, sz - len, "%sunknown(%x)", + len ? "," : "", flags); + + return buf; +} + +static void show_attach_flags_json(__u32 flags) +{ + char buf[32]; + size_t i; + + jsonw_name(json_wtr, "attach_flags"); + jsonw_start_array(json_wtr); + + for (i =3D 0; i < ARRAY_SIZE(attach_flag_names); i++) { + if (!(flags & attach_flag_names[i].flag)) + continue; + + jsonw_string(json_wtr, attach_flag_names[i].name); + flags &=3D ~attach_flag_names[i].flag; + } + + if (flags) { + snprintf(buf, sizeof(buf), "unknown(%x)", flags); + jsonw_string(json_wtr, buf); + } + + jsonw_end_array(json_wtr); +} + static int show_bpf_prog(int id, enum bpf_attach_type attach_type, - const char *attach_flags_str, - int level) + __u32 attach_flags, int level) { char prog_name[MAX_PROG_FULL_NAME]; + char attach_flags_str[64]; const char *attach_btf_name =3D NULL; struct bpf_prog_info info =3D {}; const char *attach_type_str; @@ -182,7 +240,7 @@ static int show_bpf_prog(int id, enum bpf_attach_type a= ttach_type, else jsonw_uint_field(json_wtr, "attach_type", attach_type); if (!(query_flags & BPF_F_QUERY_EFFECTIVE)) - jsonw_string_field(json_wtr, "attach_flags", attach_flags_str); + show_attach_flags_json(attach_flags); jsonw_string_field(json_wtr, "name", prog_name); if (attach_btf_name) jsonw_string_field(json_wtr, "attach_btf_name", attach_btf_name); @@ -198,7 +256,9 @@ static int show_bpf_prog(int id, enum bpf_attach_type a= ttach_type, if (query_flags & BPF_F_QUERY_EFFECTIVE) printf(" %-15s", prog_name); else - printf(" %-15s %-15s", attach_flags_str, prog_name); + printf(" %-17s %-15s", + format_attach_flags(attach_flags, attach_flags_str, + sizeof(attach_flags_str)), prog_name); if (attach_btf_name) printf(" %-15s", attach_btf_name); else if (info.attach_btf_id) @@ -264,7 +324,7 @@ static int show_effective_bpf_progs(int cgroup_fd, enum= bpf_attach_type type, return 0; =20 for (iter =3D 0; iter < p.prog_cnt; iter++) - show_bpf_prog(prog_ids[iter], type, NULL, level); + show_bpf_prog(prog_ids[iter], type, 0, level); =20 return 0; } @@ -274,9 +334,7 @@ static int show_attached_bpf_progs(int cgroup_fd, enum = bpf_attach_type type, { LIBBPF_OPTS(bpf_prog_query_opts, p); __u32 prog_attach_flags[1024] =3D {0}; - const char *attach_flags_str; __u32 prog_ids[1024] =3D {0}; - char buf[32]; __u32 iter; int ret; =20 @@ -296,24 +354,7 @@ static int show_attached_bpf_progs(int cgroup_fd, enum= bpf_attach_type type, __u32 attach_flags; =20 attach_flags =3D prog_attach_flags[iter] ?: p.attach_flags; - - switch (attach_flags) { - case BPF_F_ALLOW_MULTI: - attach_flags_str =3D "multi"; - break; - case BPF_F_ALLOW_OVERRIDE: - attach_flags_str =3D "override"; - break; - case 0: - attach_flags_str =3D ""; - break; - default: - snprintf(buf, sizeof(buf), "unknown(%x)", attach_flags); - attach_flags_str =3D buf; - } - - show_bpf_prog(prog_ids[iter], type, - attach_flags_str, level); + show_bpf_prog(prog_ids[iter], type, attach_flags, level); } =20 return 0; @@ -377,7 +418,7 @@ static int do_show(int argc, char **argv) else if (query_flags & BPF_F_QUERY_EFFECTIVE) printf("%-8s %-15s %-15s\n", "ID", "AttachType", "Name"); else - printf("%-8s %-15s %-15s %-15s\n", "ID", "AttachType", + printf("%-8s %-15s %-17s %-15s\n", "ID", "AttachType", "AttachFlags", "Name"); =20 btf_vmlinux =3D libbpf_find_kernel_btf(); @@ -531,7 +572,7 @@ static int do_show_tree(int argc, char **argv) "ID", "AttachType", "Name"); else printf("%s\n" - "%-8s %-15s %-15s %-15s\n", + "%-8s %-15s %-17s %-15s\n", "CgroupPath", "ID", "AttachType", "AttachFlags", "Name"); =20 @@ -593,6 +634,8 @@ static int do_attach(int argc, char **argv) attach_flags |=3D BPF_F_ALLOW_MULTI; } else if (is_prefix(argv[i], "override")) { attach_flags |=3D BPF_F_ALLOW_OVERRIDE; + } else if (is_prefix(argv[i], "preorder")) { + attach_flags |=3D BPF_F_PREORDER; } else { p_err("unknown option: %s", argv[i]); goto exit_cgroup; --=20 2.55.0