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 if (IS_ERR(obj)) { 50 p_err("can't open objfile %s", objfile); 51 goto close_map_fd; 52 } 53 54 err = bpf_object__load(obj); 55 if (err) { 56 p_err("can't load objfile %s", objfile); 57 goto close_obj; 58 } 59 60 prog = bpf_program__next(NULL, obj); 61 if (!prog) { 62 p_err("can't find bpf program in objfile %s", objfile); 63 goto close_obj; 64 } 65 66 link = bpf_program__attach_iter(prog, &iter_opts); 67 if (IS_ERR(link)) { 68 err = PTR_ERR(link); 69 p_err("attach_iter failed for program %s", 70 bpf_program__name(prog)); 71 goto close_obj; 72 } 73 74 err = mount_bpffs_for_pin(path); 75 if (err) 76 goto close_link; 77 78 err = bpf_link__pin(link, path); 79 if (err) { 80 p_err("pin_iter failed for program %s to path %s", 81 bpf_program__name(prog), path); 82 goto close_link; 83 } 84 85 close_link: 86 bpf_link__destroy(link); 87 close_obj: 88 bpf_object__close(obj); 89 close_map_fd: 90 if (map_fd >= 0) 91 close(map_fd); 92 return err; 93 } 94 95 static int do_help(int argc, char **argv) 96 { 97 fprintf(stderr, 98 "Usage: %1$s %2$s pin OBJ PATH [map MAP]\n" 99 " %1$s %2$s help\n" 100 "\n" 101 " " HELP_SPEC_MAP "\n" 102 " " HELP_SPEC_OPTIONS " }\n" 103 "", 104 bin_name, "iter"); 105 106 return 0; 107 } 108 109 static const struct cmd cmds[] = { 110 { "help", do_help }, 111 { "pin", do_pin }, 112 { 0 } 113 }; 114 115 int do_iter(int argc, char **argv) 116 { 117 return cmd_select(cmds, argc, argv, do_help); 118 } 119