diff options
| author | Wang Nan <wangnan0@huawei.com> | 2015-06-30 22:14:08 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-08-07 09:16:59 -0400 |
| commit | aa9b1ac33c7979d0d91eff8b70cffc4916f5555c (patch) | |
| tree | dbb31262a1ad3ed8385578e9a3783176c34277b5 | |
| parent | 55cffde2e1a41109cb49f8e94de954c8240242b5 (diff) | |
bpf tools: Introduce accessors for struct bpf_program
This patch introduces accessors for user of libbpf to retrieve section
name and fd of a opened/loaded eBPF program. 'struct bpf_prog_handler'
is used for that purpose. Accessors of programs section name and file
descriptor are provided. Set/get private data are also impelmented.
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Ahern <dsahern@gmail.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Zefan Li <lizefan@huawei.com>
Link: http://lkml.kernel.org/r/1435716878-189507-21-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/lib/bpf/libbpf.c | 72 | ||||
| -rw-r--r-- | tools/lib/bpf/libbpf.h | 24 |
2 files changed, 96 insertions, 0 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 38447b7d6e73..ae1c5cbd8158 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
| @@ -98,6 +98,10 @@ struct bpf_program { | |||
| 98 | int nr_reloc; | 98 | int nr_reloc; |
| 99 | 99 | ||
| 100 | int fd; | 100 | int fd; |
| 101 | |||
| 102 | struct bpf_object *obj; | ||
| 103 | void *priv; | ||
| 104 | bpf_program_clear_priv_t clear_priv; | ||
| 101 | }; | 105 | }; |
| 102 | 106 | ||
| 103 | struct bpf_object { | 107 | struct bpf_object { |
| @@ -150,6 +154,12 @@ static void bpf_program__exit(struct bpf_program *prog) | |||
| 150 | if (!prog) | 154 | if (!prog) |
| 151 | return; | 155 | return; |
| 152 | 156 | ||
| 157 | if (prog->clear_priv) | ||
| 158 | prog->clear_priv(prog, prog->priv); | ||
| 159 | |||
| 160 | prog->priv = NULL; | ||
| 161 | prog->clear_priv = NULL; | ||
| 162 | |||
| 153 | bpf_program__unload(prog); | 163 | bpf_program__unload(prog); |
| 154 | zfree(&prog->section_name); | 164 | zfree(&prog->section_name); |
| 155 | zfree(&prog->insns); | 165 | zfree(&prog->insns); |
| @@ -225,6 +235,7 @@ bpf_object__add_program(struct bpf_object *obj, void *data, size_t size, | |||
| 225 | pr_debug("found program %s\n", prog.section_name); | 235 | pr_debug("found program %s\n", prog.section_name); |
| 226 | obj->programs = progs; | 236 | obj->programs = progs; |
| 227 | obj->nr_programs = nr_progs + 1; | 237 | obj->nr_programs = nr_progs + 1; |
| 238 | prog.obj = obj; | ||
| 228 | progs[nr_progs] = prog; | 239 | progs[nr_progs] = prog; |
| 229 | return 0; | 240 | return 0; |
| 230 | } | 241 | } |
| @@ -931,3 +942,64 @@ void bpf_object__close(struct bpf_object *obj) | |||
| 931 | 942 | ||
| 932 | free(obj); | 943 | free(obj); |
| 933 | } | 944 | } |
| 945 | |||
| 946 | struct bpf_program * | ||
| 947 | bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) | ||
| 948 | { | ||
| 949 | size_t idx; | ||
| 950 | |||
| 951 | if (!obj->programs) | ||
| 952 | return NULL; | ||
| 953 | /* First handler */ | ||
| 954 | if (prev == NULL) | ||
| 955 | return &obj->programs[0]; | ||
| 956 | |||
| 957 | if (prev->obj != obj) { | ||
| 958 | pr_warning("error: program handler doesn't match object\n"); | ||
| 959 | return NULL; | ||
| 960 | } | ||
| 961 | |||
| 962 | idx = (prev - obj->programs) + 1; | ||
| 963 | if (idx >= obj->nr_programs) | ||
| 964 | return NULL; | ||
| 965 | return &obj->programs[idx]; | ||
| 966 | } | ||
| 967 | |||
| 968 | int bpf_program__set_private(struct bpf_program *prog, | ||
| 969 | void *priv, | ||
| 970 | bpf_program_clear_priv_t clear_priv) | ||
| 971 | { | ||
| 972 | if (prog->priv && prog->clear_priv) | ||
| 973 | prog->clear_priv(prog, prog->priv); | ||
| 974 | |||
| 975 | prog->priv = priv; | ||
| 976 | prog->clear_priv = clear_priv; | ||
| 977 | return 0; | ||
| 978 | } | ||
| 979 | |||
| 980 | int bpf_program__get_private(struct bpf_program *prog, void **ppriv) | ||
| 981 | { | ||
| 982 | *ppriv = prog->priv; | ||
| 983 | return 0; | ||
| 984 | } | ||
| 985 | |||
| 986 | const char *bpf_program__title(struct bpf_program *prog, bool dup) | ||
| 987 | { | ||
| 988 | const char *title; | ||
| 989 | |||
| 990 | title = prog->section_name; | ||
| 991 | if (dup) { | ||
| 992 | title = strdup(title); | ||
| 993 | if (!title) { | ||
| 994 | pr_warning("failed to strdup program title\n"); | ||
| 995 | return NULL; | ||
| 996 | } | ||
| 997 | } | ||
| 998 | |||
| 999 | return title; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | int bpf_program__fd(struct bpf_program *prog) | ||
| 1003 | { | ||
| 1004 | return prog->fd; | ||
| 1005 | } | ||
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 3e6960075835..657e497bd586 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #define __BPF_LIBBPF_H | 9 | #define __BPF_LIBBPF_H |
| 10 | 10 | ||
| 11 | #include <stdio.h> | 11 | #include <stdio.h> |
| 12 | #include <stdbool.h> | ||
| 12 | 13 | ||
| 13 | /* | 14 | /* |
| 14 | * In include/linux/compiler-gcc.h, __printf is defined. However | 15 | * In include/linux/compiler-gcc.h, __printf is defined. However |
| @@ -34,6 +35,29 @@ void bpf_object__close(struct bpf_object *object); | |||
| 34 | int bpf_object__load(struct bpf_object *obj); | 35 | int bpf_object__load(struct bpf_object *obj); |
| 35 | int bpf_object__unload(struct bpf_object *obj); | 36 | int bpf_object__unload(struct bpf_object *obj); |
| 36 | 37 | ||
| 38 | /* Accessors of bpf_program. */ | ||
| 39 | struct bpf_program; | ||
| 40 | struct bpf_program *bpf_program__next(struct bpf_program *prog, | ||
| 41 | struct bpf_object *obj); | ||
| 42 | |||
| 43 | #define bpf_object__for_each_program(pos, obj) \ | ||
| 44 | for ((pos) = bpf_program__next(NULL, (obj)); \ | ||
| 45 | (pos) != NULL; \ | ||
| 46 | (pos) = bpf_program__next((pos), (obj))) | ||
| 47 | |||
| 48 | typedef void (*bpf_program_clear_priv_t)(struct bpf_program *, | ||
| 49 | void *); | ||
| 50 | |||
| 51 | int bpf_program__set_private(struct bpf_program *prog, void *priv, | ||
| 52 | bpf_program_clear_priv_t clear_priv); | ||
| 53 | |||
| 54 | int bpf_program__get_private(struct bpf_program *prog, | ||
| 55 | void **ppriv); | ||
| 56 | |||
| 57 | const char *bpf_program__title(struct bpf_program *prog, bool dup); | ||
| 58 | |||
| 59 | int bpf_program__fd(struct bpf_program *prog); | ||
| 60 | |||
| 37 | /* | 61 | /* |
| 38 | * We don't need __attribute__((packed)) now since it is | 62 | * We don't need __attribute__((packed)) now since it is |
| 39 | * unnecessary for 'bpf_map_def' because they are all aligned. | 63 | * unnecessary for 'bpf_map_def' because they are all aligned. |
