mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace
@ 2026-09-22  2:54 Hui Su
  2026-09-22  2:54 ` [PATCH bpf-next v3 1/3] bpf: Report BPF_F_PREORDER in cgroup program queries Hui Su
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Hui Su @ 2026-09-22  2:54 UTC (permalink / raw)
  To: bpf, 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, linux-kernel, Hui Su

The BPF_F_PREORDER attach flag changes the ordering of programs in the
effective cgroup program array, but BPF_PROG_QUERY did not report the
per-program flag. This series exposes that state and updates bpftool to
display, accept, and document this flag.

The series is split into three patches:

1. Report BPF_F_PREORDER in direct cgroup program queries.
2. Add selftests for direct and link-based program queries.
3. Add bpftool support for text, JSON, command-line, completion, and
   documentation handling of BPF_F_PREORDER.

Changes in v3:
- Simplify the changelogs for patches 1 and 2.
- Simplify the ATTACH_FLAGS synopsis and represent attach flags as an
  array in JSON output, as suggested by Quentin Monnet.
- Widen the plain-text AttachFlags column for combined flags.
- Address checkpatch line-length and alignment warnings.

Testing:
- PASS: cgroup_mprog_opts, cgroup_preorder, and bpftool cgroup
  plain-text/JSON smoke (x86_64 QEMU/KVM).
- PASS: bpftool build, Documentation build, bash -n, and checkpatch on
  generated v3 patches.

Previous versions:
v2: https://lore.kernel.org/bpf/20260919094400.600585-1-sh_def@163.com/
v1: https://lore.kernel.org/bpf/20260918172407.3459188-1-sh_def@163.com/

Hui Su (3):
  bpf: Report BPF_F_PREORDER in cgroup program queries
  selftests/bpf: Test querying BPF_F_PREORDER cgroup attachments
  bpftool: Add support for BPF_F_PREORDER cgroup attach flag

 kernel/bpf/cgroup.c                           | 16 +--
 .../bpftool/Documentation/bpftool-cgroup.rst  | 25 +++--
 tools/bpf/bpftool/bash-completion/bpftool     |  4 +-
 tools/bpf/bpftool/cgroup.c                    | 99 +++++++++++++------
 .../bpf/prog_tests/cgroup_mprog_opts.c        | 71 ++++++++++++-
 5 files changed, 166 insertions(+), 49 deletions(-)


base-commit: 79dc258c9392051420a26f1504c647bd3d27c66a
-- 
2.55.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH bpf-next v3 1/3] bpf: Report BPF_F_PREORDER in cgroup program queries
  2026-09-22  2:54 [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace Hui Su
@ 2026-09-22  2:54 ` Hui Su
  2026-09-22  2:54 ` [PATCH bpf-next v3 2/3] selftests/bpf: Test querying BPF_F_PREORDER cgroup attachments Hui Su
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Hui Su @ 2026-09-22  2:54 UTC (permalink / raw)
  To: bpf, 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, linux-kernel, Hui Su

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 <sh_def@163.com>
---

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 unchanged.

 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 = prog_list_id(pl);
 				if (copy_to_user(prog_ids + i, &id, sizeof(id)))
 					return -EFAULT;
+				if (prog_attach_flags) {
+					flags = cgrp->bpf.flags[atype] |
+						(pl->flags & BPF_F_PREORDER);
+					if (copy_to_user(prog_attach_flags + i,
+							 &flags, sizeof(flags)))
+						return -EFAULT;
+				}
 				if (++i == cnt)
 					break;
 			}
 
-			if (prog_attach_flags) {
-				flags = cgrp->bpf.flags[atype];
-
-				for (i = 0; i < cnt; i++)
-					if (copy_to_user(prog_attach_flags + i,
-							 &flags, sizeof(flags)))
-						return -EFAULT;
+			if (prog_attach_flags)
 				prog_attach_flags += cnt;
-			}
 		}
 
 		prog_ids += cnt;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH bpf-next v3 2/3] selftests/bpf: Test querying BPF_F_PREORDER cgroup attachments
  2026-09-22  2:54 [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace Hui Su
  2026-09-22  2:54 ` [PATCH bpf-next v3 1/3] bpf: Report BPF_F_PREORDER in cgroup program queries Hui Su
@ 2026-09-22  2:54 ` Hui Su
  2026-09-22  2:54 ` [PATCH bpf-next v3 3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag Hui Su
  2026-09-24 21:20 ` [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace patchwork-bot+netdevbpf
  3 siblings, 0 replies; 6+ messages in thread
From: Hui Su @ 2026-09-22  2:54 UTC (permalink / raw)
  To: bpf, 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, linux-kernel, Hui Su

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 <sh_def@163.com>
---

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 unchanged.

 .../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/tools/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);
 }
 
+static int find_prog_attach_flags(const struct bpf_prog_query_opts *opts,
+				  __u32 prog_id, __u32 *flags)
+{
+	__u32 i;
+
+	for (i = 0; i < opts->count; i++) {
+		if (opts->prog_ids[i] == prog_id) {
+			*flags = 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] = {};
+	__u32 prog_ids[10] = {};
+	__u32 flags;
+	int err;
+
+	optq.prog_ids = prog_ids;
+	optq.prog_attach_flags = prog_attach_flags;
+	optq.count = 10;
+	err = 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 = find_prog_attach_flags(&optq, id1, &flags);
+	if (ASSERT_OK(err, "find id1"))
+		ASSERT_EQ(flags, BPF_F_ALLOW_MULTI, "flags id1");
+
+	err = 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 = 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 = 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;
 
@@ -294,6 +347,11 @@ static void test_preorder_prog_attach_detach(int atype)
 	fd3 = bpf_program__fd(skel->progs.getsockopt_3);
 	fd4 = bpf_program__fd(skel->progs.getsockopt_4);
 
+	id1 = id_from_prog_fd(fd1);
+	id2 = id_from_prog_fd(fd2);
+	id3 = id_from_prog_fd(fd3);
+	id4 = id_from_prog_fd(fd4);
+
 	assert_mprog_count(cg, atype, 0);
 
 	LIBBPF_OPTS_RESET(opta,
@@ -357,6 +415,8 @@ static void test_preorder_prog_attach_detach(int atype)
 
 	assert_mprog_count(cg, atype, 4);
 
+	assert_preorder_query_flags(cg, atype, id1, id2, id3, id4);
+
 	err = 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;
 
 	cg = test__join_cgroup("/preorder_link_attach_detach");
@@ -399,6 +459,11 @@ static void test_preorder_link_attach_detach(int atype)
 
 	fd2 = bpf_program__fd(skel->progs.getsockopt_2);
 
+	id1 = id_from_prog_fd(bpf_program__fd(skel->progs.getsockopt_1));
+	id2 = id_from_prog_fd(fd2);
+	id3 = id_from_prog_fd(bpf_program__fd(skel->progs.getsockopt_3));
+	id4 = id_from_prog_fd(bpf_program__fd(skel->progs.getsockopt_4));
+
 	assert_mprog_count(cg, atype, 0);
 
 	LIBBPF_OPTS_RESET(opta,
@@ -460,6 +525,8 @@ static void test_preorder_link_attach_detach(int atype)
 
 	assert_mprog_count(cg, atype, 4);
 
+	assert_preorder_query_flags(cg, atype, id1, id2, id3, id4);
+
 	bpf_link__destroy(link4);
 	assert_mprog_count(cg, atype, 3);
 
-- 
2.55.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH bpf-next v3 3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag
  2026-09-22  2:54 [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace Hui Su
  2026-09-22  2:54 ` [PATCH bpf-next v3 1/3] bpf: Report BPF_F_PREORDER in cgroup program queries Hui Su
  2026-09-22  2:54 ` [PATCH bpf-next v3 2/3] selftests/bpf: Test querying BPF_F_PREORDER cgroup attachments Hui Su
@ 2026-09-22  2:54 ` Hui Su
  2026-09-22 10:23   ` Quentin Monnet
  2026-09-24 21:20 ` [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace patchwork-bot+netdevbpf
  3 siblings, 1 reply; 6+ messages in thread
From: Hui Su @ 2026-09-22  2:54 UTC (permalink / raw)
  To: bpf, 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, linux-kernel, Hui Su

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 <cg>
  1234  cgroup_inet_ingress  unknown(42)  test_prog
  $ bpftool cgroup attach <cg> cgroup_inet_ingress id 5678 multi preorder
  Error: unknown option: preorder

After:
  $ bpftool cgroup show <cg>
  1234  cgroup_inet_ingress  multi,preorder  test_prog
  $ bpftool cgroup attach <cg> 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 <sh_def@163.com>
---

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 rebase).
    - PASS: bash -n tools/bpf/bpftool/bash-completion/bpftool (fresh after rebase).
    - PASS: bpftool cgroup plain-text and JSON runtime smoke (x86_64 QEMU/KVM); 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* := { **multi** | **override** }
+| *ATTACH_FLAGS* := { [ **multi** | **override** ] [ **preorder** ] }
 
 DESCRIPTION
 ===========
@@ -75,20 +75,27 @@ bpftool cgroup attach *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
     Attach program *PROG* to the cgroup *CGROUP* with attach type *ATTACH_TYPE*
     and optional *ATTACH_FLAGS*.
 
-    *ATTACH_FLAGS* can be one of: **override** if a sub-cgroup installs some
+    *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 program
-    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 program,
+    before non-preorder programs, which execute descendants-to-ancestors
+    across the cgroup hierarchy. Note that **preorder** alone does not enable
+    multi-program attachment; specify **multi** together with **preorder** to
+    attach multiple programs.
 
-    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 program
+    replaces the existing program, provided the **override** setting matches.
 
     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 programs
+    in the effective program array. Within each ordering class at the same
+    cgroup level, attachment order is preserved.
 
-    Non-default *ATTACH_FLAGS* are supported by kernel version 4.14 and later.
+    **multi** and **override** are supported by kernel version 4.14 and later.
+    **preorder** was introduced upstream in Linux 6.15.
 
     *ATTACH_TYPE* can be one of:
 
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="$(bpftool feature list_builtins attach_types 2>/dev/null | \
                         grep '^cgroup_')"
-                    local ATTACH_FLAGS='multi override'
                     # Check for $prev = $command first
                     if [ $prev = $command ]; then
                         _filedir
@@ -1094,7 +1093,8 @@ _bpftool()
                                 # "id|pinned|tag|name" (we already checked for
                                 # that). This should only leave the case when
                                 # we need attach flags for "attach" commamnd.
-                                _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[] = {
 };
 
 #define HELP_SPEC_ATTACH_FLAGS						\
-	"ATTACH_FLAGS := { multi | override }"
+	"ATTACH_FLAGS := { [ multi | override ] [ preorder ] }"
 
 #define HELP_SPEC_ATTACH_TYPES						\
 	"       ATTACH_TYPE := { cgroup_inet_ingress | cgroup_inet_egress |\n" \
@@ -138,11 +138,69 @@ static void guess_vmlinux_btf_id(__u32 attach_btf_obj_id)
 	close(fd);
 }
 
+static const struct {
+	__u32 flag;
+	const char *name;
+} attach_flag_names[] = {
+	{ 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 = 0;
+	size_t i;
+	int n;
+
+	buf[0] = '\0';
+	for (i = 0; i < ARRAY_SIZE(attach_flag_names); i++) {
+		if (flags & attach_flag_names[i].flag) {
+			n = snprintf(buf + len, sz - len, "%s%s",
+				     len ? "," : "", attach_flag_names[i].name);
+			if (n < 0 || (size_t)n >= sz - len)
+				return buf;
+			len += n;
+			flags &= ~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 = 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 &= ~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 = NULL;
 	struct bpf_prog_info info = {};
 	const char *attach_type_str;
@@ -182,7 +240,7 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_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 attach_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;
 
 	for (iter = 0; iter < p.prog_cnt; iter++)
-		show_bpf_prog(prog_ids[iter], type, NULL, level);
+		show_bpf_prog(prog_ids[iter], type, 0, level);
 
 	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] = {0};
-	const char *attach_flags_str;
 	__u32 prog_ids[1024] = {0};
-	char buf[32];
 	__u32 iter;
 	int ret;
 
@@ -296,24 +354,7 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
 		__u32 attach_flags;
 
 		attach_flags = prog_attach_flags[iter] ?: p.attach_flags;
-
-		switch (attach_flags) {
-		case BPF_F_ALLOW_MULTI:
-			attach_flags_str = "multi";
-			break;
-		case BPF_F_ALLOW_OVERRIDE:
-			attach_flags_str = "override";
-			break;
-		case 0:
-			attach_flags_str = "";
-			break;
-		default:
-			snprintf(buf, sizeof(buf), "unknown(%x)", attach_flags);
-			attach_flags_str = buf;
-		}
-
-		show_bpf_prog(prog_ids[iter], type,
-			      attach_flags_str, level);
+		show_bpf_prog(prog_ids[iter], type, attach_flags, level);
 	}
 
 	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");
 
 	btf_vmlinux = 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");
 
@@ -593,6 +634,8 @@ static int do_attach(int argc, char **argv)
 			attach_flags |= BPF_F_ALLOW_MULTI;
 		} else if (is_prefix(argv[i], "override")) {
 			attach_flags |= BPF_F_ALLOW_OVERRIDE;
+		} else if (is_prefix(argv[i], "preorder")) {
+			attach_flags |= BPF_F_PREORDER;
 		} else {
 			p_err("unknown option: %s", argv[i]);
 			goto exit_cgroup;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH bpf-next v3 3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag
  2026-09-22  2:54 ` [PATCH bpf-next v3 3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag Hui Su
@ 2026-09-22 10:23   ` Quentin Monnet
  0 siblings, 0 replies; 6+ messages in thread
From: Quentin Monnet @ 2026-09-22 10:23 UTC (permalink / raw)
  To: Hui Su, bpf, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Yonghong Song, Martin KaFai Lau, Song Liu, Jiri Olsa,
	Emil Tsalapatis, Ihor Solodrai, Shuah Khan, linux-kselftest,
	linux-kernel

2026-09-22 11:54 UTC+0900 ~ Hui Su <sh_def@163.com>
> 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 <cg>
>   1234  cgroup_inet_ingress  unknown(42)  test_prog
>   $ bpftool cgroup attach <cg> cgroup_inet_ingress id 5678 multi preorder
>   Error: unknown option: preorder
> 
> After:
>   $ bpftool cgroup show <cg>
>   1234  cgroup_inet_ingress  multi,preorder  test_prog
>   $ bpftool cgroup attach <cg> 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 <sh_def@163.com>

Acked-by: Quentin Monnet <qmo@kernel.org>

Thank you

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace
  2026-09-22  2:54 [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace Hui Su
                   ` (2 preceding siblings ...)
  2026-09-22  2:54 ` [PATCH bpf-next v3 3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag Hui Su
@ 2026-09-24 21:20 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-09-24 21:20 UTC (permalink / raw)
  To: Hui Su
  Cc: bpf, ast, daniel, andrii, eddyz87, memxor, yonghong.song, qmo,
	martin.lau, song, jolsa, emil, ihor.solodrai, shuah,
	linux-kselftest, linux-kernel

Hello:

This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Tue, 22 Sep 2026 11:54:39 +0900 you wrote:
> The BPF_F_PREORDER attach flag changes the ordering of programs in the
> effective cgroup program array, but BPF_PROG_QUERY did not report the
> per-program flag. This series exposes that state and updates bpftool to
> display, accept, and document this flag.
> 
> The series is split into three patches:
> 
> [...]

Here is the summary with links:
  - [bpf-next,v3,1/3] bpf: Report BPF_F_PREORDER in cgroup program queries
    https://git.kernel.org/bpf/bpf-next/c/9ed640ee09ab
  - [bpf-next,v3,2/3] selftests/bpf: Test querying BPF_F_PREORDER cgroup attachments
    https://git.kernel.org/bpf/bpf-next/c/47211d1200f0
  - [bpf-next,v3,3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag
    https://git.kernel.org/bpf/bpf-next/c/c39bf6b6705f

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-24 21:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-22  2:54 [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace Hui Su
2026-09-22  2:54 ` [PATCH bpf-next v3 1/3] bpf: Report BPF_F_PREORDER in cgroup program queries Hui Su
2026-09-22  2:54 ` [PATCH bpf-next v3 2/3] selftests/bpf: Test querying BPF_F_PREORDER cgroup attachments Hui Su
2026-09-22  2:54 ` [PATCH bpf-next v3 3/3] bpftool: Add support for BPF_F_PREORDER cgroup attach flag Hui Su
2026-09-22 10:23   ` Quentin Monnet
2026-09-24 21:20 ` [PATCH bpf-next v3 0/3] bpf: expose cgroup preorder attachment state to userspace patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®