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