xref: /aosp_15_r20/external/bpftool/src/iter.c (revision 858ea5e570667251cdc31d3fe7b846b591105938)
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