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