Merge tag 'v5.9' into next
[linux-2.6-microblaze.git] / tools / bpf / bpftool / iter.c
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                 "       " HELP_SPEC_MAP "\n"
101                 "",
102                 bin_name, "iter");
103
104         return 0;
105 }
106
107 static const struct cmd cmds[] = {
108         { "help",       do_help },
109         { "pin",        do_pin },
110         { 0 }
111 };
112
113 int do_iter(int argc, char **argv)
114 {
115         return cmd_select(cmds, argc, argv, do_help);
116 }