lkml.org 
[lkml]   [2015]   [May]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v2 24/37] tools lib bpf: accessors of bpf_program.
    Date
    This patch introduces accessors for user of libbpf to retrive 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>
    ---
    tools/lib/bpf/libbpf.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++
    tools/lib/bpf/libbpf.h | 25 +++++++++
    2 files changed, 162 insertions(+)

    diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
    index e8ef78e..d770adc 100644
    --- a/tools/lib/bpf/libbpf.c
    +++ b/tools/lib/bpf/libbpf.c
    @@ -79,6 +79,20 @@ void libbpf_set_print(int (*warn)(const char *format, ...),
    # define LIBBPF_ELF_C_READ_MMAP ELF_C_READ
    #endif

    +#ifndef container_of
    +# define container_of(ptr, type, member) ({ \
    + const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    + (type *)( (char *)__mptr - offsetof(type,member) );})
    +#endif
    +
    +/* Accessing of project */
    +struct bpf_prog_handler {
    + struct bpf_object *obj;
    +
    + void *priv;
    + bpf_prog_clear_priv_t clear_priv;
    +};
    +
    /*
    * bpf_prog should be a better name but it has been used in
    * linux/filter.h.
    @@ -97,6 +111,7 @@ struct bpf_program {
    int nr_reloc;

    int fd;
    + struct bpf_prog_handler handler;
    };

    struct bpf_object {
    @@ -146,6 +161,12 @@ static void bpf_clear_program(struct bpf_program *prog)
    if (!prog)
    return;

    + if (prog->handler.clear_priv)
    + prog->handler.clear_priv(&prog->handler, prog->handler.priv);
    +
    + prog->handler.priv = NULL;
    + prog->handler.clear_priv = NULL;
    +
    bpf_unload_program(prog);

    if (prog->section_name) {
    @@ -217,6 +238,7 @@ bpf_program_alloc(struct bpf_object *obj, void *data, size_t size,
    prog->insns_cnt * sizeof(struct bpf_insn));
    prog->idx = idx;
    prog->fd = -1;
    + prog->handler.obj = obj;

    return prog;
    out:
    @@ -941,3 +963,118 @@ void bpf_close_object(struct bpf_object *obj)
    }
    free(obj);
    }
    +
    +static inline struct bpf_program *
    +handler_to_prog(struct bpf_prog_handler *handler)
    +{
    + struct bpf_program *prog;
    + struct bpf_object *obj;
    + size_t idx;
    +
    + if (!handler)
    + goto out_warn;
    +
    + obj = handler->obj;
    + prog = container_of(handler, struct bpf_program, handler);
    + idx = prog - obj->programs;
    + if (idx >= obj->nr_programs)
    + goto out_warn;
    + return &obj->programs[idx];
    +
    +out_warn:
    + pr_warning("invalid handler %p\n", handler);
    + return NULL;
    +}
    +
    +struct bpf_prog_handler *
    +bpf_next_prog(struct bpf_object *obj, struct bpf_prog_handler *handler)
    +{
    + struct bpf_program *prog;
    + size_t idx;
    +
    + if (!obj->programs)
    + return NULL;
    + /* First handler */
    + if (handler == NULL)
    + return (&obj->programs[0].handler);
    +
    + if (handler->obj != obj) {
    + pr_warning("error: program handler doesn't "
    + "match object\n");
    + return NULL;
    + }
    +
    + prog = handler_to_prog(handler);
    + if (!prog)
    + return NULL;
    +
    + idx = (prog - obj->programs) + 1;
    + if (idx >= obj->nr_programs)
    + return NULL;
    + return &obj->programs[idx].handler;
    +}
    +
    +int bpf_prog_set_private(struct bpf_prog_handler *handler, void *priv,
    + bpf_prog_clear_priv_t clear_priv)
    +{
    + struct bpf_program *prog;
    +
    + prog = handler_to_prog(handler);
    + if (!prog)
    + return -EINVAL;
    +
    + if (prog->handler.priv && prog->handler.clear_priv)
    + prog->handler.clear_priv(&prog->handler, prog->handler.priv);
    +
    + prog->handler.priv = priv;
    + prog->handler.clear_priv = clear_priv;
    + return 0;
    +}
    +
    +int bpf_prog_get_private(struct bpf_prog_handler *handler, void **ppriv)
    +{
    + struct bpf_program *prog;
    +
    + prog = handler_to_prog(handler);
    + if (!prog || !ppriv)
    + return -EINVAL;
    +
    + *ppriv = prog->handler.priv;
    + return 0;
    +}
    +
    +int bpf_prog_get_title(struct bpf_prog_handler *handler,
    + const char **ptitle, bool dup)
    +{
    + struct bpf_program *prog;
    + const char *title;
    +
    + prog = handler_to_prog(handler);
    + if (!prog || !ptitle)
    + return -EINVAL;
    +
    + title = prog->section_name;
    + if (dup) {
    + title = strdup(title);
    + if (!title) {
    + pr_warning("failed to strdup program title\n");
    + *ptitle = NULL;
    + return -ENOMEM;
    + }
    + }
    +
    + *ptitle = title;
    + return 0;
    +}
    +
    +int bpf_prog_get_fd(struct bpf_prog_handler *handler, int *pfd)
    +{
    + struct bpf_program *prog;
    +
    + prog = handler_to_prog(handler);
    + if (!prog || !pfd)
    + return -EINVAL;
    +
    + *pfd = prog->fd;
    + return 0;
    +}
    diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
    index c0b290d..b451d1a 100644
    --- a/tools/lib/bpf/libbpf.h
    +++ b/tools/lib/bpf/libbpf.h
    @@ -10,6 +10,7 @@
    #define __BPF_LIBBPF_H

    #include <stdio.h>
    +#include <stdbool.h>

    void libbpf_set_print(int (*warn)(const char *format, ...),
    int (*info)(const char *format, ...),
    @@ -25,6 +26,30 @@ void bpf_close_object(struct bpf_object *object);
    int bpf_load_object(struct bpf_object *obj);
    int bpf_unload_object(struct bpf_object *obj);

    +/* Accessors of bpf_program. */
    +struct bpf_prog_handler;
    +struct bpf_prog_handler *bpf_next_prog(struct bpf_object *obj,
    + struct bpf_prog_handler *handler);
    +
    +#define bpf_obj_for_each_prog(obj, pos) \
    + for ((pos) = bpf_next_prog((obj), NULL); \
    + (pos) != NULL; \
    + (pos) = bpf_next_prog((obj), (pos)))
    +
    +typedef void (*bpf_prog_clear_priv_t)(struct bpf_prog_handler *,
    + void *);
    +
    +int bpf_prog_set_private(struct bpf_prog_handler *handler, void *priv,
    + bpf_prog_clear_priv_t clear_priv);
    +
    +int bpf_prog_get_private(struct bpf_prog_handler *handler,
    + void **ppriv);
    +
    +int bpf_prog_get_title(struct bpf_prog_handler *handler,
    + const char **ptitle, bool dup);
    +
    +int bpf_prog_get_fd(struct bpf_prog_handler *handler, int *pfd);
    +
    /*
    * packed attribute is unnecessary for 'bpf_map_def'.
    */
    --
    1.8.3.4


    \
     
     \ /
      Last update: 2015-05-15 10:01    [W:2.153 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site