0001
0002
0003
0004 #define _GNU_SOURCE
0005 #include <unistd.h>
0006 #include <linux/err.h>
0007 #include <bpf/libbpf.h>
0008
0009 #include "main.h"
0010
0011 static int do_pin(int argc, char **argv)
0012 {
0013 DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts);
0014 union bpf_iter_link_info linfo;
0015 const char *objfile, *path;
0016 struct bpf_program *prog;
0017 struct bpf_object *obj;
0018 struct bpf_link *link;
0019 int err = -1, map_fd = -1;
0020
0021 if (!REQ_ARGS(2))
0022 usage();
0023
0024 objfile = GET_ARG();
0025 path = GET_ARG();
0026
0027
0028 if (argc) {
0029 if (is_prefix(*argv, "map")) {
0030 NEXT_ARG();
0031
0032 if (!REQ_ARGS(2)) {
0033 p_err("incorrect map spec");
0034 return -1;
0035 }
0036
0037 map_fd = map_parse_fd(&argc, &argv);
0038 if (map_fd < 0)
0039 return -1;
0040
0041 memset(&linfo, 0, sizeof(linfo));
0042 linfo.map.map_fd = map_fd;
0043 iter_opts.link_info = &linfo;
0044 iter_opts.link_info_len = sizeof(linfo);
0045 }
0046 }
0047
0048 obj = bpf_object__open(objfile);
0049 err = libbpf_get_error(obj);
0050 if (err) {
0051 p_err("can't open objfile %s", objfile);
0052 goto close_map_fd;
0053 }
0054
0055 err = bpf_object__load(obj);
0056 if (err) {
0057 p_err("can't load objfile %s", objfile);
0058 goto close_obj;
0059 }
0060
0061 prog = bpf_object__next_program(obj, NULL);
0062 if (!prog) {
0063 p_err("can't find bpf program in objfile %s", objfile);
0064 goto close_obj;
0065 }
0066
0067 link = bpf_program__attach_iter(prog, &iter_opts);
0068 err = libbpf_get_error(link);
0069 if (err) {
0070 p_err("attach_iter failed for program %s",
0071 bpf_program__name(prog));
0072 goto close_obj;
0073 }
0074
0075 err = mount_bpffs_for_pin(path);
0076 if (err)
0077 goto close_link;
0078
0079 err = bpf_link__pin(link, path);
0080 if (err) {
0081 p_err("pin_iter failed for program %s to path %s",
0082 bpf_program__name(prog), path);
0083 goto close_link;
0084 }
0085
0086 close_link:
0087 bpf_link__destroy(link);
0088 close_obj:
0089 bpf_object__close(obj);
0090 close_map_fd:
0091 if (map_fd >= 0)
0092 close(map_fd);
0093 return err;
0094 }
0095
0096 static int do_help(int argc, char **argv)
0097 {
0098 fprintf(stderr,
0099 "Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"
0100 " %1$s %2$s help\n"
0101 "\n"
0102 " " HELP_SPEC_MAP "\n"
0103 " " HELP_SPEC_OPTIONS " }\n"
0104 "",
0105 bin_name, "iter");
0106
0107 return 0;
0108 }
0109
0110 static const struct cmd cmds[] = {
0111 { "help", do_help },
0112 { "pin", do_pin },
0113 { 0 }
0114 };
0115
0116 int do_iter(int argc, char **argv)
0117 {
0118 return cmd_select(cmds, argc, argv, do_help);
0119 }