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
425 __aligned_u64 line_info; /* line info */425 __aligned_u64 line_info; /* line info */
426 __u32 line_info_cnt; /* number of bpf_line_info records */426 __u32 line_info_cnt; /* number of bpf_line_info records */
427 __u32 attach_btf_id; /* in-kernel BTF type id to attach to */427 __u32 attach_btf_id; /* in-kernel BTF type id to attach to */
428 __u32 attach_prog_fd; /* 0 to attach to vmlinux */
428 };429 };
429 430
430 struct { /* anonymous struct used by BPF_OBJ_* commands */431 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
228 memset(&attr, 0, sizeof(attr));228 memset(&attr, 0, sizeof(attr));
229 attr.prog_type = load_attr->prog_type;229 attr.prog_type = load_attr->prog_type;
230 attr.expected_attach_type = load_attr->expected_attach_type;230 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) {
232 attr.attach_btf_id = load_attr->attach_btf_id;232 attr.attach_btf_id = load_attr->attach_btf_id;
233 else233 attr.attach_prog_fd = load_attr->attach_prog_fd;
234 } else {
234 attr.prog_ifindex = load_attr->prog_ifindex;235 attr.prog_ifindex = load_attr->prog_ifindex;
236 attr.kern_version = load_attr->kern_version;
237 }
235 attr.insn_cnt = (__u32)load_attr->insns_cnt;238 attr.insn_cnt = (__u32)load_attr->insns_cnt;
236 attr.insns = ptr_to_u64(load_attr->insns);239 attr.insns = ptr_to_u64(load_attr->insns);
237 attr.license = ptr_to_u64(load_attr->license);240 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
245 attr.log_size = 0;248 attr.log_size = 0;
246 }249 }
247 250
248 attr.kern_version = load_attr->kern_version;
249 attr.prog_btf_fd = load_attr->prog_btf_fd;251 attr.prog_btf_fd = load_attr->prog_btf_fd;
250 attr.func_info_rec_size = load_attr->func_info_rec_size;252 attr.func_info_rec_size = load_attr->func_info_rec_size;
251 attr.func_info_cnt = load_attr->func_info_cnt;253 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
77 const struct bpf_insn *insns;77 const struct bpf_insn *insns;
78 size_t insns_cnt;78 size_t insns_cnt;
79 const char *license;79 const char *license;
80 __u32 kern_version;80 union {
81 __u32 kern_version;
82 __u32 attach_prog_fd;
83 };
81 union {84 union {
82 __u32 prog_ifindex;85 __u32 prog_ifindex;
83 __u32 attach_btf_id;86 __u32 attach_btf_id;
tools/lib/bpf/libbpf.c+59−12
@@ -189,6 +189,7 @@ struct bpf_program { · 188 unmodified lines
189 189
190 enum bpf_attach_type expected_attach_type;190 enum bpf_attach_type expected_attach_type;
191 __u32 attach_btf_id;191 __u32 attach_btf_id;
192 __u32 attach_prog_fd;
192 void *func_info;193 void *func_info;
193 __u32 func_info_rec_size;194 __u32 func_info_rec_size;
194 __u32 func_info_cnt;195 __u32 func_info_cnt;
@@ -3683,8 +3684,13 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, · 3488 unmodified lines
3683 load_attr.insns = insns;3684 load_attr.insns = insns;
3684 load_attr.insns_cnt = insns_cnt;3685 load_attr.insns_cnt = insns_cnt;
3685 load_attr.license = license;3686 load_attr.license = license;
3686 load_attr.kern_version = kern_version;3687 if (prog->type == BPF_PROG_TYPE_TRACING) {
3687 load_attr.prog_ifindex = prog->prog_ifindex;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 }
3688 /* if .BTF.ext was loaded, kernel supports associated BTF for prog */3694 /* if .BTF.ext was loaded, kernel supports associated BTF for prog */
3689 if (prog->obj->btf_ext)3695 if (prog->obj->btf_ext)
3690 btf_fd = bpf_object__btf_fd(prog->obj);3696 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
3699 load_attr.line_info_cnt = prog->line_info_cnt;3705 load_attr.line_info_cnt = prog->line_info_cnt;
3700 load_attr.log_level = prog->log_level;3706 load_attr.log_level = prog->log_level;
3701 load_attr.prog_flags = prog->prog_flags;3707 load_attr.prog_flags = prog->prog_flags;
3702 load_attr.attach_btf_id = prog->attach_btf_id;
3703 3708
3704retry_load:3709retry_load:
3705 log_buf = malloc(log_buf_size);3710 log_buf = malloc(log_buf_size);
@@ -3856,9 +3861,9 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level) · 150 unmodified lines
3856 return 0;3861 return 0;
3857}3862}
3858 3863
3859static int libbpf_attach_btf_id_by_name(const char *name,3864static int libbpf_find_attach_btf_id(const char *name,
3860 enum bpf_attach_type attach_type);3865 enum bpf_attach_type attach_type,
3861 3866 __u32 attach_prog_fd);
3862static struct bpf_object *3867static struct bpf_object *
3863__bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz,3868__bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz,
3864 struct bpf_object_open_opts *opts)3869 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
3869 const char *obj_name;3874 const char *obj_name;
3870 char tmp_name[64];3875 char tmp_name[64];
3871 bool relaxed_maps;3876 bool relaxed_maps;
3877 __u32 attach_prog_fd;
3872 int err;3878 int err;
3873 3879
3874 if (elf_version(EV_CURRENT) == EV_NONE) {3880 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
3899 obj->relaxed_core_relocs = OPTS_GET(opts, relaxed_core_relocs, false);3905 obj->relaxed_core_relocs = OPTS_GET(opts, relaxed_core_relocs, false);
3900 relaxed_maps = OPTS_GET(opts, relaxed_maps, false);3906 relaxed_maps = OPTS_GET(opts, relaxed_maps, false);
3901 pin_root_path = OPTS_GET(opts, pin_root_path, NULL);3907 pin_root_path = OPTS_GET(opts, pin_root_path, NULL);
3908 attach_prog_fd = OPTS_GET(opts, attach_prog_fd, 0);
3902 3909
3903 CHECK_ERR(bpf_object__elf_init(obj), err, out);3910 CHECK_ERR(bpf_object__elf_init(obj), err, out);
3904 CHECK_ERR(bpf_object__check_endianness(obj), err, out);3911 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
3923 bpf_program__set_type(prog, prog_type);3930 bpf_program__set_type(prog, prog_type);
3924 bpf_program__set_expected_attach_type(prog, attach_type);3931 bpf_program__set_expected_attach_type(prog, attach_type);
3925 if (prog_type == BPF_PROG_TYPE_TRACING) {3932 if (prog_type == BPF_PROG_TYPE_TRACING) {
3926 err = libbpf_attach_btf_id_by_name(prog->section_name,3933 err = libbpf_find_attach_btf_id(prog->section_name,
3927 attach_type);3934 attach_type,
3935 attach_prog_fd);
3928 if (err <= 0)3936 if (err <= 0)
3929 goto out;3937 goto out;
3930 prog->attach_btf_id = err;3938 prog->attach_btf_id = err;
3939 prog->attach_prog_fd = attach_prog_fd;
3931 }3940 }
3932 }3941 }
3933 3942
@@ -5086,8 +5095,42 @@ int libbpf_find_vmlinux_btf_id(const char *name, · 1152 unmodified lines
5086 return err;5095 return err;
5087}5096}
5088 5097
5089static int libbpf_attach_btf_id_by_name(const char *name,5098static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)
5090 enum bpf_attach_type attach_type)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 }
5126out:
5127 free(info_linear);
5128 return err;
5129}
5130
5131static int libbpf_find_attach_btf_id(const char *name,
5132 enum bpf_attach_type attach_type,
5133 __u32 attach_prog_fd)
5091{5134{
5092 int i, err;5135 int i, err;
5093 5136
@@ -5099,8 +5142,12 @@ static int libbpf_attach_btf_id_by_name(const char *name, · 5 unmodified lines
5099 continue;5142 continue;
5100 if (strncmp(name, section_names[i].sec, section_names[i].len))5143 if (strncmp(name, section_names[i].sec, section_names[i].len))
5101 continue;5144 continue;
5102 err = libbpf_find_vmlinux_btf_id(name + section_names[i].len,5145 if (attach_prog_fd)
5103 attach_type);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);
5104 if (err <= 0)5151 if (err <= 0)
5105 pr_warn("%s is not found in vmlinux BTF\n", name);5152 pr_warn("%s is not found in vmlinux BTF\n", name);
5106 return err;5153 return err;
tools/lib/bpf/libbpf.h+2−1
@@ -108,8 +108,9 @@ struct bpf_object_open_opts { · 107 unmodified lines
108 * auto-pinned to that path on load; defaults to "/sys/fs/bpf".108 * auto-pinned to that path on load; defaults to "/sys/fs/bpf".
109 */109 */
110 const char *pin_root_path;110 const char *pin_root_path;
111 __u32 attach_prog_fd;
111};112};
112#define bpf_object_open_opts__last_field pin_root_path113#define bpf_object_open_opts__last_field attach_prog_fd
113 114
114LIBBPF_API struct bpf_object *bpf_object__open(const char *path);115LIBBPF_API struct bpf_object *bpf_object__open(const char *path);
115LIBBPF_API struct bpf_object *116LIBBPF_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