aboutsummaryrefslogtreecommitdiffstats
path: root/tools/bpf/bpftool/prog.c
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2018-07-10 17:43:03 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-07-11 16:13:34 -0400
commitc8406848badd0a0b040b0d286e612678662a2ab3 (patch)
tree268065cfe8a88a0dd001d3fb0808526d473568bf /tools/bpf/bpftool/prog.c
parent07f2d4eac2a850fc9649b27aa935cdcd263fb1ff (diff)
tools: bpftool: reimplement bpf_prog_load() for prog load
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 <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools/bpf/bpftool/prog.c')
-rw-r--r--tools/bpf/bpftool/prog.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 98695585bbb6..2bdd5ecd1aad 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -43,6 +43,8 @@
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/stat.h> 44#include <sys/stat.h>
45 45
46#include <linux/err.h>
47
46#include <bpf.h> 48#include <bpf.h>
47#include <libbpf.h> 49#include <libbpf.h>
48 50
@@ -682,17 +684,20 @@ static int do_pin(int argc, char **argv)
682 684
683static int do_load(int argc, char **argv) 685static int do_load(int argc, char **argv)
684{ 686{
685 struct bpf_prog_load_attr attr = { 687 enum bpf_attach_type expected_attach_type;
688 struct bpf_object_open_attr attr = {
686 .prog_type = BPF_PROG_TYPE_UNSPEC, 689 .prog_type = BPF_PROG_TYPE_UNSPEC,
687 }; 690 };
688 const char *objfile, *pinfile; 691 struct bpf_program *prog;
689 struct bpf_object *obj; 692 struct bpf_object *obj;
690 int prog_fd; 693 struct bpf_map *map;
694 const char *pinfile;
695 __u32 ifindex = 0;
691 int err; 696 int err;
692 697
693 if (!REQ_ARGS(2)) 698 if (!REQ_ARGS(2))
694 return -1; 699 return -1;
695 objfile = GET_ARG(); 700 attr.file = GET_ARG();
696 pinfile = GET_ARG(); 701 pinfile = GET_ARG();
697 702
698 while (argc) { 703 while (argc) {
@@ -719,7 +724,7 @@ static int do_load(int argc, char **argv)
719 strcat(type, "/"); 724 strcat(type, "/");
720 725
721 err = libbpf_prog_type_by_name(type, &attr.prog_type, 726 err = libbpf_prog_type_by_name(type, &attr.prog_type,
722 &attr.expected_attach_type); 727 &expected_attach_type);
723 free(type); 728 free(type);
724 if (err < 0) { 729 if (err < 0) {
725 p_err("unknown program type '%s'", *argv); 730 p_err("unknown program type '%s'", *argv);
@@ -729,15 +734,15 @@ static int do_load(int argc, char **argv)
729 } else if (is_prefix(*argv, "dev")) { 734 } else if (is_prefix(*argv, "dev")) {
730 NEXT_ARG(); 735 NEXT_ARG();
731 736
732 if (attr.ifindex) { 737 if (ifindex) {
733 p_err("offload device already specified"); 738 p_err("offload device already specified");
734 return -1; 739 return -1;
735 } 740 }
736 if (!REQ_ARGS(1)) 741 if (!REQ_ARGS(1))
737 return -1; 742 return -1;
738 743
739 attr.ifindex = if_nametoindex(*argv); 744 ifindex = if_nametoindex(*argv);
740 if (!attr.ifindex) { 745 if (!ifindex) {
741 p_err("unrecognized netdevice '%s': %s", 746 p_err("unrecognized netdevice '%s': %s",
742 *argv, strerror(errno)); 747 *argv, strerror(errno));
743 return -1; 748 return -1;
@@ -750,14 +755,44 @@ static int do_load(int argc, char **argv)
750 } 755 }
751 } 756 }
752 757
753 attr.file = objfile; 758 obj = bpf_object__open_xattr(&attr);
754 759 if (IS_ERR_OR_NULL(obj)) {
755 if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) { 760 p_err("failed to open object file");
756 p_err("failed to load program");
757 return -1; 761 return -1;
758 } 762 }
759 763
760 if (do_pin_fd(prog_fd, pinfile)) 764 prog = bpf_program__next(NULL, obj);
765 if (!prog) {
766 p_err("object file doesn't contain any bpf program");
767 goto err_close_obj;
768 }
769
770 bpf_program__set_ifindex(prog, ifindex);
771 if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) {
772 const char *sec_name = bpf_program__title(prog, false);
773
774 err = libbpf_prog_type_by_name(sec_name, &attr.prog_type,
775 &expected_attach_type);
776 if (err < 0) {
777 p_err("failed to guess program type based on section name %s\n",
778 sec_name);
779 goto err_close_obj;
780 }
781 }
782 bpf_program__set_type(prog, attr.prog_type);
783 bpf_program__set_expected_attach_type(prog, expected_attach_type);
784
785 bpf_map__for_each(map, obj)
786 if (!bpf_map__is_offload_neutral(map))
787 bpf_map__set_ifindex(map, ifindex);
788
789 err = bpf_object__load(obj);
790 if (err) {
791 p_err("failed to load object file");
792 goto err_close_obj;
793 }
794
795 if (do_pin_fd(bpf_program__fd(prog), pinfile))
761 goto err_close_obj; 796 goto err_close_obj;
762 797
763 if (json_output) 798 if (json_output)