1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 // Copyright (C) 2020 Facebook 3 4 #define _GNU_SOURCE 5 #include <unistd.h> 6 #include <linux/err.h> 7 #include <bpf/libbpf.h> 8 9 #include "main.h" 10 11 static int do_pin(int argc, char **argv) 12 { 13 DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts); 14 union bpf_iter_link_info linfo; 15 const char *objfile, *path; 16 struct bpf_program *prog; 17 struct bpf_object *obj; 18 struct bpf_link *link; 19 int err = -1, map_fd = -1; 20 21 if (!REQ_ARGS(2)) 22 usage(); 23 24 objfile = GET_ARG(); 25 path = GET_ARG(); 26 27 /* optional arguments */ 28 if (argc) { 29 if (is_prefix(*argv, "map")) { 30 NEXT_ARG(); 31 32 if (!REQ_ARGS(2)) { 33 p_err("incorrect map spec"); 34 return -1; 35 } 36 37 map_fd = map_parse_fd(&argc, &argv); 38 if (map_fd < 0) 39 return -1; 40 41 memset(&linfo, 0, sizeof(linfo)); 42 linfo.map.map_fd = map_fd; 43 iter_opts.link_info = &linfo; 44 iter_opts.link_info_len = sizeof(linfo); 45 } 46 } 47 48 obj = bpf_object__open(objfile); 49 err = libbpf_get_error(obj); 50 if (err) { 51 p_err("can't open objfile %s", objfile); 52 goto close_map_fd; 53 } 54 55 err = bpf_object__load(obj); 56 if (err) { 57 p_err("can't load objfile %s", objfile); 58 goto close_obj; 59 } 60 61 prog = bpf_object__next_program(obj, NULL); 62 if (!prog) { 63 p_err("can't find bpf program in objfile %s", objfile); 64 goto close_obj; 65 } 66 67 link = bpf_program__attach_iter(prog, &iter_opts); 68 err = libbpf_get_error(link); 69 if (err) { 70 p_err("attach_iter failed for program %s", 71 bpf_program__name(prog)); 72 goto close_obj; 73 } 74 75 err = mount_bpffs_for_pin(path); 76 if (err) 77 goto close_link; 78 79 err = bpf_link__pin(link, path); 80 if (err) { 81 p_err("pin_iter failed for program %s to path %s", 82 bpf_program__name(prog), path); 83 goto close_link; 84 } 85 86 close_link: 87 bpf_link__destroy(link); 88 close_obj: 89 bpf_object__close(obj); 90 close_map_fd: 91 if (map_fd >= 0) 92 close(map_fd); 93 return err; 94 } 95 96 static int do_help(int argc, char **argv) 97 { 98 fprintf(stderr, 99 "Usage: %1$s %2$s pin OBJ PATH [map MAP]\n" 100 " %1$s %2$s help\n" 101 "\n" 102 " " HELP_SPEC_MAP "\n" 103 " " HELP_SPEC_OPTIONS " }\n" 104 "", 105 bin_name, "iter"); 106 107 return 0; 108 } 109 110 static const struct cmd cmds[] = { 111 { "help", do_help }, 112 { "pin", do_pin }, 113 { 0 } 114 }; 115 116 int do_iter(int argc, char **argv) 117 { 118 return cmd_select(cmds, argc, argv, do_help); 119 } 120