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