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