This adds a configure check for libbpf and renames functions to allow lib/bpf.c to be compiled with it present. This makes it possible to port functionality piecemeal to use libbpf. Signed-off-by: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> --- configure | 16 ++++++++++++++++ include/bpf_util.h | 6 +++--- ip/ipvrf.c | 4 ++-- lib/bpf.c | 33 +++++++++++++++++++-------------- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/configure b/configure index 45fcffb6..5a89ee9f 100755 --- a/configure +++ b/configure @@ -238,6 +238,19 @@ check_elf() fi } +check_libbpf() +{ + if ${PKG_CONFIG} libbpf --exists; then + echo "HAVE_LIBBPF:=y" >>$CONFIG + echo "yes" + + echo 'CFLAGS += -DHAVE_LIBBPF' `${PKG_CONFIG} libbpf --cflags` >> $CONFIG + echo 'LDLIBS += ' `${PKG_CONFIG} libbpf --libs` >>$CONFIG + else + echo "no" + fi +} + check_selinux() # SELinux is a compile time option in the ss utility { @@ -386,6 +399,9 @@ check_selinux echo -n "ELF support: " check_elf +echo -n "libbpf support: " +check_libbpf + echo -n "libmnl support: " check_mnl diff --git a/include/bpf_util.h b/include/bpf_util.h index 63db07ca..72d3a32c 100644 --- a/include/bpf_util.h +++ b/include/bpf_util.h @@ -274,9 +274,9 @@ int bpf_trace_pipe(void); void bpf_print_ops(struct rtattr *bpf_ops, __u16 len); -int bpf_prog_load(enum bpf_prog_type type, const struct bpf_insn *insns, - size_t size_insns, const char *license, char *log, - size_t size_log); +int bpf_prog_load_buf(enum bpf_prog_type type, const struct bpf_insn *insns, + size_t size_insns, const char *license, char *log, + size_t size_log); int bpf_prog_attach_fd(int prog_fd, int target_fd, enum bpf_attach_type type); int bpf_prog_detach_fd(int target_fd, enum bpf_attach_type type); diff --git a/ip/ipvrf.c b/ip/ipvrf.c index 43366f6e..1d1aae6f 100644 --- a/ip/ipvrf.c +++ b/ip/ipvrf.c @@ -256,8 +256,8 @@ static int prog_load(int idx) BPF_EXIT_INSN(), }; - return bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, prog, sizeof(prog), - "GPL", bpf_log_buf, sizeof(bpf_log_buf)); + return bpf_prog_load_buf(BPF_PROG_TYPE_CGROUP_SOCK, prog, sizeof(prog), + "GPL", bpf_log_buf, sizeof(bpf_log_buf)); } static int vrf_configure_cgroup(const char *path, int ifindex) diff --git a/lib/bpf.c b/lib/bpf.c index 7d2a322f..c6e3bd0d 100644 --- a/lib/bpf.c +++ b/lib/bpf.c @@ -28,6 +28,11 @@ #include <gelf.h> #endif +#ifdef HAVE_LIBBPF +#include <bpf/libbpf.h> +#include <bpf/bpf.h> +#endif + #include <sys/types.h> #include <sys/stat.h> #include <sys/un.h> @@ -795,7 +800,7 @@ out: return mnt; } -static int bpf_obj_get(const char *pathname, enum bpf_prog_type type) +static int bpf_obj_get_path(const char *pathname, enum bpf_prog_type type) { union bpf_attr attr = {}; char tmp[PATH_MAX]; @@ -814,7 +819,7 @@ static int bpf_obj_get(const char *pathname, enum bpf_prog_type type) static int bpf_obj_pinned(const char *pathname, enum bpf_prog_type type) { - int prog_fd = bpf_obj_get(pathname, type); + int prog_fd = bpf_obj_get_path(pathname, type); if (prog_fd < 0) fprintf(stderr, "Couldn\'t retrieve pinned program \'%s\': %s\n", @@ -1036,7 +1041,7 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv) } } - map_fd = bpf_obj_get(map_path, cfg.type); + map_fd = bpf_obj_get_path(map_path, cfg.type); if (map_fd < 0) { fprintf(stderr, "Couldn\'t retrieve pinned map \'%s\': %s\n", map_path, strerror(errno)); @@ -1105,9 +1110,9 @@ static int bpf_prog_load_dev(enum bpf_prog_type type, return bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); } -int bpf_prog_load(enum bpf_prog_type type, const struct bpf_insn *insns, - size_t size_insns, const char *license, char *log, - size_t size_log) +int bpf_prog_load_buf(enum bpf_prog_type type, const struct bpf_insn *insns, + size_t size_insns, const char *license, char *log, + size_t size_log) { return bpf_prog_load_dev(type, insns, size_insns, license, 0, log, size_log); @@ -1284,7 +1289,7 @@ static int bpf_btf_load(void *btf, size_t size_btf, return bpf(BPF_BTF_LOAD, &attr, sizeof(attr)); } -static int bpf_obj_pin(int fd, const char *pathname) +static int bpf_obj_pin_fd(int fd, const char *pathname) { union bpf_attr attr = {}; @@ -1433,7 +1438,7 @@ static int bpf_probe_pinned(const char *name, const struct bpf_elf_ctx *ctx, return 0; bpf_make_pathname(pathname, sizeof(pathname), name, ctx, pinning); - return bpf_obj_get(pathname, ctx->type); + return bpf_obj_get_path(pathname, ctx->type); } static int bpf_make_obj_path(const struct bpf_elf_ctx *ctx) @@ -1501,7 +1506,7 @@ static int bpf_place_pinned(int fd, const char *name, return ret; bpf_make_pathname(pathname, sizeof(pathname), name, ctx, pinning); - return bpf_obj_pin(fd, pathname); + return bpf_obj_pin_fd(fd, pathname); } static void bpf_prog_report(int fd, const char *section, @@ -1523,9 +1528,9 @@ static void bpf_prog_report(int fd, const char *section, bpf_dump_error(ctx, "Verifier analysis:\n\n"); } -static int bpf_prog_attach(const char *section, - const struct bpf_elf_prog *prog, - struct bpf_elf_ctx *ctx) +static int bpf_prog_attach_section(const char *section, + const struct bpf_elf_prog *prog, + struct bpf_elf_ctx *ctx) { int tries = 0, fd; retry: @@ -2347,7 +2352,7 @@ static int bpf_fetch_prog(struct bpf_elf_ctx *ctx, const char *section, prog.insns_num = prog.size / sizeof(struct bpf_insn); prog.insns = data.sec_data->d_buf; - fd = bpf_prog_attach(section, &prog, ctx); + fd = bpf_prog_attach_section(section, &prog, ctx); if (fd < 0) return fd; @@ -2513,7 +2518,7 @@ static int bpf_fetch_prog_relo(struct bpf_elf_ctx *ctx, const char *section, goto out; } - fd = bpf_prog_attach(section, prog, ctx); + fd = bpf_prog_attach_section(section, prog, ctx); free(prog->insns); if (fd < 0) { *lderr = true; -- 2.22.1