Commit 1d671166 authored by Yonghong Song's avatar Yonghong Song Committed by Andrii Nakryiko
Browse files

libbpf: Support link-based cgroup attach with options



Currently libbpf supports bpf_program__attach_cgroup() with signature:
  LIBBPF_API struct bpf_link *
  bpf_program__attach_cgroup(const struct bpf_program *prog, int cgroup_fd);

To support mprog style attachment, additionsl fields like flags,
relative_{fd,id} and expected_revision are needed.

Add a new API:
  LIBBPF_API struct bpf_link *
  bpf_program__attach_cgroup_opts(const struct bpf_program *prog, int cgroup_fd,
                                  const struct bpf_cgroup_opts *opts);
where bpf_cgroup_opts contains all above needed fields.

Signed-off-by: default avatarYonghong Song <yonghong.song@linux.dev>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20250606163146.2429212-1-yonghong.song@linux.dev
parent 12093398
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -837,6 +837,50 @@ int bpf_link_create(int prog_fd, int target_fd,
		if (!OPTS_ZEROED(opts, netkit))
			return libbpf_err(-EINVAL);
		break;
	case BPF_CGROUP_INET_INGRESS:
	case BPF_CGROUP_INET_EGRESS:
	case BPF_CGROUP_INET_SOCK_CREATE:
	case BPF_CGROUP_INET_SOCK_RELEASE:
	case BPF_CGROUP_INET4_BIND:
	case BPF_CGROUP_INET6_BIND:
	case BPF_CGROUP_INET4_POST_BIND:
	case BPF_CGROUP_INET6_POST_BIND:
	case BPF_CGROUP_INET4_CONNECT:
	case BPF_CGROUP_INET6_CONNECT:
	case BPF_CGROUP_UNIX_CONNECT:
	case BPF_CGROUP_INET4_GETPEERNAME:
	case BPF_CGROUP_INET6_GETPEERNAME:
	case BPF_CGROUP_UNIX_GETPEERNAME:
	case BPF_CGROUP_INET4_GETSOCKNAME:
	case BPF_CGROUP_INET6_GETSOCKNAME:
	case BPF_CGROUP_UNIX_GETSOCKNAME:
	case BPF_CGROUP_UDP4_SENDMSG:
	case BPF_CGROUP_UDP6_SENDMSG:
	case BPF_CGROUP_UNIX_SENDMSG:
	case BPF_CGROUP_UDP4_RECVMSG:
	case BPF_CGROUP_UDP6_RECVMSG:
	case BPF_CGROUP_UNIX_RECVMSG:
	case BPF_CGROUP_SOCK_OPS:
	case BPF_CGROUP_DEVICE:
	case BPF_CGROUP_SYSCTL:
	case BPF_CGROUP_GETSOCKOPT:
	case BPF_CGROUP_SETSOCKOPT:
	case BPF_LSM_CGROUP:
		relative_fd = OPTS_GET(opts, cgroup.relative_fd, 0);
		relative_id = OPTS_GET(opts, cgroup.relative_id, 0);
		if (relative_fd && relative_id)
			return libbpf_err(-EINVAL);
		if (relative_id) {
			attr.link_create.cgroup.relative_id = relative_id;
			attr.link_create.flags |= BPF_F_ID;
		} else {
			attr.link_create.cgroup.relative_fd = relative_fd;
		}
		attr.link_create.cgroup.expected_revision =
			OPTS_GET(opts, cgroup.expected_revision, 0);
		if (!OPTS_ZEROED(opts, cgroup))
			return libbpf_err(-EINVAL);
		break;
	default:
		if (!OPTS_ZEROED(opts, flags))
			return libbpf_err(-EINVAL);
+5 −0
Original line number Diff line number Diff line
@@ -438,6 +438,11 @@ struct bpf_link_create_opts {
			__u32 relative_id;
			__u64 expected_revision;
		} netkit;
		struct {
			__u32 relative_fd;
			__u32 relative_id;
			__u64 expected_revision;
		} cgroup;
	};
	size_t :0;
};
+28 −0
Original line number Diff line number Diff line
@@ -12837,6 +12837,34 @@ struct bpf_link *bpf_program__attach_xdp(const struct bpf_program *prog, int ifi
	return bpf_program_attach_fd(prog, ifindex, "xdp", NULL);
}

struct bpf_link *
bpf_program__attach_cgroup_opts(const struct bpf_program *prog, int cgroup_fd,
				const struct bpf_cgroup_opts *opts)
{
	LIBBPF_OPTS(bpf_link_create_opts, link_create_opts);
	__u32 relative_id;
	int relative_fd;

	if (!OPTS_VALID(opts, bpf_cgroup_opts))
		return libbpf_err_ptr(-EINVAL);

	relative_id = OPTS_GET(opts, relative_id, 0);
	relative_fd = OPTS_GET(opts, relative_fd, 0);

	if (relative_fd && relative_id) {
		pr_warn("prog '%s': relative_fd and relative_id cannot be set at the same time\n",
			prog->name);
		return libbpf_err_ptr(-EINVAL);
	}

	link_create_opts.cgroup.expected_revision = OPTS_GET(opts, expected_revision, 0);
	link_create_opts.cgroup.relative_fd = relative_fd;
	link_create_opts.cgroup.relative_id = relative_id;
	link_create_opts.flags = OPTS_GET(opts, flags, 0);

	return bpf_program_attach_fd(prog, cgroup_fd, "cgroup", &link_create_opts);
}

struct bpf_link *
bpf_program__attach_tcx(const struct bpf_program *prog, int ifindex,
			const struct bpf_tcx_opts *opts)
+15 −0
Original line number Diff line number Diff line
@@ -877,6 +877,21 @@ LIBBPF_API struct bpf_link *
bpf_program__attach_netkit(const struct bpf_program *prog, int ifindex,
			   const struct bpf_netkit_opts *opts);

struct bpf_cgroup_opts {
	/* size of this struct, for forward/backward compatibility */
	size_t sz;
	__u32 flags;
	__u32 relative_fd;
	__u32 relative_id;
	__u64 expected_revision;
	size_t :0;
};
#define bpf_cgroup_opts__last_field expected_revision

LIBBPF_API struct bpf_link *
bpf_program__attach_cgroup_opts(const struct bpf_program *prog, int cgroup_fd,
				const struct bpf_cgroup_opts *opts);

struct bpf_map;

LIBBPF_API struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map);
+1 −0
Original line number Diff line number Diff line
@@ -437,6 +437,7 @@ LIBBPF_1.6.0 {
		bpf_linker__add_fd;
		bpf_linker__new_fd;
		bpf_object__prepare;
		bpf_program__attach_cgroup_opts;
		bpf_program__func_info;
		bpf_program__func_info_cnt;
		bpf_program__line_info;