xref: /linux/tools/bpf/bpftool/iter.c (revision 24bce201d79807b668bf9d9e0aca801c5c0d5f78)
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 	err = libbpf_get_error(obj);
50 	if (err) {
51 		p_err("can't open objfile %s", objfile);
52 		goto close_map_fd;
53 	}
54 
55 	err = bpf_object__load(obj);
56 	if (err) {
57 		p_err("can't load objfile %s", objfile);
58 		goto close_obj;
59 	}
60 
61 	prog = bpf_object__next_program(obj, NULL);
62 	if (!prog) {
63 		p_err("can't find bpf program in objfile %s", objfile);
64 		goto close_obj;
65 	}
66 
67 	link = bpf_program__attach_iter(prog, &iter_opts);
68 	err = libbpf_get_error(link);
69 	if (err) {
70 		p_err("attach_iter failed for program %s",
71 		      bpf_program__name(prog));
72 		goto close_obj;
73 	}
74 
75 	err = mount_bpffs_for_pin(path);
76 	if (err)
77 		goto close_link;
78 
79 	err = bpf_link__pin(link, path);
80 	if (err) {
81 		p_err("pin_iter failed for program %s to path %s",
82 		      bpf_program__name(prog), path);
83 		goto close_link;
84 	}
85 
86 close_link:
87 	bpf_link__destroy(link);
88 close_obj:
89 	bpf_object__close(obj);
90 close_map_fd:
91 	if (map_fd >= 0)
92 		close(map_fd);
93 	return err;
94 }
95 
96 static int do_help(int argc, char **argv)
97 {
98 	fprintf(stderr,
99 		"Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"
100 		"       %1$s %2$s help\n"
101 		"\n"
102 		"       " HELP_SPEC_MAP "\n"
103 		"       " HELP_SPEC_OPTIONS " }\n"
104 		"",
105 		bin_name, "iter");
106 
107 	return 0;
108 }
109 
110 static const struct cmd cmds[] = {
111 	{ "help",	do_help },
112 	{ "pin",	do_pin },
113 	{ 0 }
114 };
115 
116 int do_iter(int argc, char **argv)
117 {
118 	return cmd_select(cmds, argc, argv, do_help);
119 }
120