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