From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jakub Kicinski Subject: [PATCH bpf-next 09/11] tools: bpftool: reimplement bpf_prog_load() for prog load Date: Tue, 3 Jul 2018 19:54:15 -0700 Message-ID: <20180704025417.8848-10-jakub.kicinski@netronome.com> References: <20180704025417.8848-1-jakub.kicinski@netronome.com> Cc: oss-drivers@netronome.com, netdev@vger.kernel.org, Jakub Kicinski To: alexei.starovoitov@gmail.com, daniel@iogearbox.net Return-path: Received: from mail-qt0-f194.google.com ([209.85.216.194]:34822 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932802AbeGDCzB (ORCPT ); Tue, 3 Jul 2018 22:55:01 -0400 Received: by mail-qt0-f194.google.com with SMTP id z6-v6so3447097qti.2 for ; Tue, 03 Jul 2018 19:55:01 -0700 (PDT) In-Reply-To: <20180704025417.8848-1-jakub.kicinski@netronome.com> Sender: netdev-owner@vger.kernel.org List-ID: bpf_prog_load() is a very useful helper but it doesn't give us full flexibility of modifying the BPF objects before loading. Open code bpf_prog_load() in bpftool so we can add extra logic in following commits. Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet --- tools/bpf/bpftool/prog.c | 57 ++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 7a06fd4c5d27..267d653c93f5 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -43,6 +43,8 @@ #include #include +#include + #include #include @@ -682,12 +684,15 @@ static int do_pin(int argc, char **argv) static int do_load(int argc, char **argv) { - struct bpf_prog_load_attr attr = { + enum bpf_attach_type expected_attach_type; + struct bpf_object_open_attr attr = { .prog_type = BPF_PROG_TYPE_UNSPEC, }; const char *objfile, *pinfile; + struct bpf_program *prog; struct bpf_object *obj; - int prog_fd; + struct bpf_map *map; + __u32 ifindex = 0; int err; if (!REQ_ARGS(2)) @@ -719,7 +724,7 @@ static int do_load(int argc, char **argv) strcat(type, "/"); err = libbpf_prog_type_by_string(type, &attr.prog_type, - &attr.expected_attach_type); + &expected_attach_type); free(type); if (err < 0) { p_err("unknown program type '%s'", *argv); @@ -729,15 +734,15 @@ static int do_load(int argc, char **argv) } else if (is_prefix(*argv, "dev")) { NEXT_ARG(); - if (attr.ifindex) { + if (ifindex) { p_err("offload device already specified"); return -1; } if (!REQ_ARGS(1)) return -1; - attr.ifindex = if_nametoindex(*argv); - if (!attr.ifindex) { + ifindex = if_nametoindex(*argv); + if (!ifindex) { p_err("unrecognized netdevice '%s': %s", *argv, strerror(errno)); return -1; @@ -750,14 +755,44 @@ static int do_load(int argc, char **argv) } } - attr.file = objfile; - - if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) { - p_err("failed to load program"); + obj = bpf_object__open_xattr(objfile, &attr); + if (IS_ERR_OR_NULL(obj)) { + p_err("failed to open object file"); return -1; } - if (do_pin_fd(prog_fd, pinfile)) + prog = bpf_program__next(NULL, obj); + if (!prog) { + p_err("object file doesn't contain any bpf program"); + goto err_close_obj; + } + + bpf_program__set_ifindex(prog, ifindex); + if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) { + const char *sec_name = bpf_program__title(prog, false); + + err = libbpf_prog_type_by_string(sec_name, &attr.prog_type, + &expected_attach_type); + if (err < 0) { + p_err("failed to guess program type based on section name %s\n", + sec_name); + goto err_close_obj; + } + } + bpf_program__set_type(prog, attr.prog_type); + bpf_program__set_expected_attach_type(prog, expected_attach_type); + + bpf_map__for_each(map, obj) + if (!bpf_map__is_offload_neutral(map)) + bpf_map__set_ifindex(map, ifindex); + + err = bpf_object__load(obj); + if (err) { + p_err("failed to load object file"); + goto err_close_obj; + } + + if (do_pin_fd(bpf_program__fd(prog), pinfile)) goto err_close_obj; if (json_output) -- 2.17.1