History

libbpf: Add support for attaching BPF programs to other BPF programs

Extend libbpf api to pass attach_prog_fd into bpf_object__open.

Alexei Starovoitov committed 7 years ago

Commit e7bf94d1 parent 5b92a285 files · +71 −17Browse files

Unified · Split

5 files
  1. tools/include/uapi/linux/bpf.h +1 −0
  2. tools/lib/bpf/bpf.c +5 −3
  3. tools/lib/bpf/bpf.h +4 −1
  4. tools/lib/bpf/libbpf.c +59 −12
  5. tools/lib/bpf/libbpf.h +2 −1
tools/include/uapi/linux/bpf.h+1−0
@@ -425,6 +425,7 @@ union bpf_attr { · 424 unmodified lines
425425 __aligned_u64 line_info; /* line info */
426426 __u32 line_info_cnt; /* number of bpf_line_info records */
427427 __u32 attach_btf_id; /* in-kernel BTF type id to attach to */
428+ __u32 attach_prog_fd; /* 0 to attach to vmlinux */
428429 };
429430
430431 struct { /* anonymous struct used by BPF_OBJ_* commands */
tools/lib/bpf/bpf.c+5−3
@@ -228,10 +228,13 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, · 227 unmodified lines
228228 memset(&attr, 0, sizeof(attr));
229229 attr.prog_type = load_attr->prog_type;
230230 attr.expected_attach_type = load_attr->expected_attach_type;
231− if (attr.prog_type == BPF_PROG_TYPE_TRACING)
231+ if (attr.prog_type == BPF_PROG_TYPE_TRACING) {
232232 attr.attach_btf_id = load_attr->attach_btf_id;
233− else
233+ attr.attach_prog_fd = load_attr->attach_prog_fd;
234+ } else {
234235 attr.prog_ifindex = load_attr->prog_ifindex;
236+ attr.kern_version = load_attr->kern_version;
237+ }
235238 attr.insn_cnt = (__u32)load_attr->insns_cnt;
236239 attr.insns = ptr_to_u64(load_attr->insns);
237240 attr.license = ptr_to_u64(load_attr->license);
@@ -245,7 +248,6 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, · 7 unmodified lines
245248 attr.log_size = 0;
246249 }
247250
248− attr.kern_version = load_attr->kern_version;
249251 attr.prog_btf_fd = load_attr->prog_btf_fd;
250252 attr.func_info_rec_size = load_attr->func_info_rec_size;
251253 attr.func_info_cnt = load_attr->func_info_cnt;
tools/lib/bpf/bpf.h+4−1
@@ -77,7 +77,10 @@ struct bpf_load_program_attr { · 76 unmodified lines
7777 const struct bpf_insn *insns;
7878 size_t insns_cnt;
7979 const char *license;
80− __u32 kern_version;
80+ union {
81+ __u32 kern_version;
82+ __u32 attach_prog_fd;
83+ };
8184 union {
8285 __u32 prog_ifindex;
8386 __u32 attach_btf_id;
tools/lib/bpf/libbpf.c+59−12
@@ -189,6 +189,7 @@ struct bpf_program { · 188 unmodified lines
189189
190190 enum bpf_attach_type expected_attach_type;
191191 __u32 attach_btf_id;
192+ __u32 attach_prog_fd;
192193 void *func_info;
193194 __u32 func_info_rec_size;
194195 __u32 func_info_cnt;
@@ -3683,8 +3684,13 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, · 3488 unmodified lines
36833684 load_attr.insns = insns;
36843685 load_attr.insns_cnt = insns_cnt;
36853686 load_attr.license = license;
3686− load_attr.kern_version = kern_version;
3687− load_attr.prog_ifindex = prog->prog_ifindex;
3687+ if (prog->type == BPF_PROG_TYPE_TRACING) {
3688+ load_attr.attach_prog_fd = prog->attach_prog_fd;
3689+ load_attr.attach_btf_id = prog->attach_btf_id;
3690+ } else {
3691+ load_attr.kern_version = kern_version;
3692+ load_attr.prog_ifindex = prog->prog_ifindex;
3693+ }
36883694 /* if .BTF.ext was loaded, kernel supports associated BTF for prog */
36893695 if (prog->obj->btf_ext)
36903696 btf_fd = bpf_object__btf_fd(prog->obj);
@@ -3699,7 +3705,6 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, · 8 unmodified lines
36993705 load_attr.line_info_cnt = prog->line_info_cnt;
37003706 load_attr.log_level = prog->log_level;
37013707 load_attr.prog_flags = prog->prog_flags;
3702− load_attr.attach_btf_id = prog->attach_btf_id;
37033708
37043709 retry_load:
37053710 log_buf = malloc(log_buf_size);
@@ -3856,9 +3861,9 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level) · 150 unmodified lines
38563861 return 0;
38573862 }
38583863
3859−static int libbpf_attach_btf_id_by_name(const char *name,
3860− enum bpf_attach_type attach_type);
3861−
3864+static int libbpf_find_attach_btf_id(const char *name,
3865+ enum bpf_attach_type attach_type,
3866+ __u32 attach_prog_fd);
38623867 static struct bpf_object *
38633868 __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz,
38643869 struct bpf_object_open_opts *opts)
@@ -3869,6 +3874,7 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz, · 4 unmodified lines
38693874 const char *obj_name;
38703875 char tmp_name[64];
38713876 bool relaxed_maps;
3877+ __u32 attach_prog_fd;
38723878 int err;
38733879
38743880 if (elf_version(EV_CURRENT) == EV_NONE) {
@@ -3899,6 +3905,7 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz, · 24 unmodified lines
38993905 obj->relaxed_core_relocs = OPTS_GET(opts, relaxed_core_relocs, false);
39003906 relaxed_maps = OPTS_GET(opts, relaxed_maps, false);
39013907 pin_root_path = OPTS_GET(opts, pin_root_path, NULL);
3908+ attach_prog_fd = OPTS_GET(opts, attach_prog_fd, 0);
39023909
39033910 CHECK_ERR(bpf_object__elf_init(obj), err, out);
39043911 CHECK_ERR(bpf_object__check_endianness(obj), err, out);
@@ -3923,11 +3930,13 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz, · 18 unmodified lines
39233930 bpf_program__set_type(prog, prog_type);
39243931 bpf_program__set_expected_attach_type(prog, attach_type);
39253932 if (prog_type == BPF_PROG_TYPE_TRACING) {
3926− err = libbpf_attach_btf_id_by_name(prog->section_name,
3927− attach_type);
3933+ err = libbpf_find_attach_btf_id(prog->section_name,
3934+ attach_type,
3935+ attach_prog_fd);
39283936 if (err <= 0)
39293937 goto out;
39303938 prog->attach_btf_id = err;
3939+ prog->attach_prog_fd = attach_prog_fd;
39313940 }
39323941 }
39333942
@@ -5086,8 +5095,42 @@ int libbpf_find_vmlinux_btf_id(const char *name, · 1152 unmodified lines
50865095 return err;
50875096 }
50885097
5089−static int libbpf_attach_btf_id_by_name(const char *name,
5090− enum bpf_attach_type attach_type)
5098+static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)
5099+{
5100+ struct bpf_prog_info_linear *info_linear;
5101+ struct bpf_prog_info *info;
5102+ struct btf *btf = NULL;
5103+ int err = -EINVAL;
5104+
5105+ info_linear = bpf_program__get_prog_info_linear(attach_prog_fd, 0);
5106+ if (IS_ERR_OR_NULL(info_linear)) {
5107+ pr_warn("failed get_prog_info_linear for FD %d\n",
5108+ attach_prog_fd);
5109+ return -EINVAL;
5110+ }
5111+ info = &info_linear->info;
5112+ if (!info->btf_id) {
5113+ pr_warn("The target program doesn't have BTF\n");
5114+ goto out;
5115+ }
5116+ if (btf__get_from_id(info->btf_id, &btf)) {
5117+ pr_warn("Failed to get BTF of the program\n");
5118+ goto out;
5119+ }
5120+ err = btf__find_by_name_kind(btf, name, BTF_KIND_FUNC);
5121+ btf__free(btf);
5122+ if (err <= 0) {
5123+ pr_warn("%s is not found in prog's BTF\n", name);
5124+ goto out;
5125+ }
5126+out:
5127+ free(info_linear);
5128+ return err;
5129+}
5130+
5131+static int libbpf_find_attach_btf_id(const char *name,
5132+ enum bpf_attach_type attach_type,
5133+ __u32 attach_prog_fd)
50915134 {
50925135 int i, err;
50935136
@@ -5099,8 +5142,12 @@ static int libbpf_attach_btf_id_by_name(const char *name, · 5 unmodified lines
50995142 continue;
51005143 if (strncmp(name, section_names[i].sec, section_names[i].len))
51015144 continue;
5102− err = libbpf_find_vmlinux_btf_id(name + section_names[i].len,
5103− attach_type);
5145+ if (attach_prog_fd)
5146+ err = libbpf_find_prog_btf_id(name + section_names[i].len,
5147+ attach_prog_fd);
5148+ else
5149+ err = libbpf_find_vmlinux_btf_id(name + section_names[i].len,
5150+ attach_type);
51045151 if (err <= 0)
51055152 pr_warn("%s is not found in vmlinux BTF\n", name);
51065153 return err;
tools/lib/bpf/libbpf.h+2−1
@@ -108,8 +108,9 @@ struct bpf_object_open_opts { · 107 unmodified lines
108108 * auto-pinned to that path on load; defaults to "/sys/fs/bpf".
109109 */
110110 const char *pin_root_path;
111+ __u32 attach_prog_fd;
111112 };
112−#define bpf_object_open_opts__last_field pin_root_path
113+#define bpf_object_open_opts__last_field attach_prog_fd
113114
114115 LIBBPF_API struct bpf_object *bpf_object__open(const char *path);
115116 LIBBPF_API struct bpf_object *

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t