xref: /linux/tools/bpf/bpftool/iter.c (revision 621cde16e49b3ecf7d59a8106a20aaebfb4a59a9)
19406b485SYonghong Song // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
29406b485SYonghong Song // Copyright (C) 2020 Facebook
39406b485SYonghong Song 
4b3d84af7SQuentin Monnet #ifndef _GNU_SOURCE
59406b485SYonghong Song #define _GNU_SOURCE
6b3d84af7SQuentin Monnet #endif
7d1313e01SSahid Orentino Ferdjaoui #include <errno.h>
8d8793acaSYonghong Song #include <unistd.h>
99406b485SYonghong Song #include <linux/err.h>
109406b485SYonghong Song #include <bpf/libbpf.h>
119406b485SYonghong Song 
129406b485SYonghong Song #include "main.h"
139406b485SYonghong Song 
do_pin(int argc,char ** argv)149406b485SYonghong Song static int do_pin(int argc, char **argv)
159406b485SYonghong Song {
16d8793acaSYonghong Song 	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts);
1774fc097dSYonghong Song 	union bpf_iter_link_info linfo;
189406b485SYonghong Song 	const char *objfile, *path;
199406b485SYonghong Song 	struct bpf_program *prog;
209406b485SYonghong Song 	struct bpf_object *obj;
219406b485SYonghong Song 	struct bpf_link *link;
22d8793acaSYonghong Song 	int err = -1, map_fd = -1;
239406b485SYonghong Song 
249406b485SYonghong Song 	if (!REQ_ARGS(2))
259406b485SYonghong Song 		usage();
269406b485SYonghong Song 
279406b485SYonghong Song 	objfile = GET_ARG();
289406b485SYonghong Song 	path = GET_ARG();
299406b485SYonghong Song 
30d8793acaSYonghong Song 	/* optional arguments */
31d8793acaSYonghong Song 	if (argc) {
32d8793acaSYonghong Song 		if (is_prefix(*argv, "map")) {
33d8793acaSYonghong Song 			NEXT_ARG();
34d8793acaSYonghong Song 
35d8793acaSYonghong Song 			if (!REQ_ARGS(2)) {
36d8793acaSYonghong Song 				p_err("incorrect map spec");
37d8793acaSYonghong Song 				return -1;
38d8793acaSYonghong Song 			}
39d8793acaSYonghong Song 
40d8793acaSYonghong Song 			map_fd = map_parse_fd(&argc, &argv);
41d8793acaSYonghong Song 			if (map_fd < 0)
42d8793acaSYonghong Song 				return -1;
4374fc097dSYonghong Song 
4474fc097dSYonghong Song 			memset(&linfo, 0, sizeof(linfo));
4574fc097dSYonghong Song 			linfo.map.map_fd = map_fd;
4674fc097dSYonghong Song 			iter_opts.link_info = &linfo;
4774fc097dSYonghong Song 			iter_opts.link_info_len = sizeof(linfo);
48d8793acaSYonghong Song 		}
49d8793acaSYonghong Song 	}
50d8793acaSYonghong Song 
519406b485SYonghong Song 	obj = bpf_object__open(objfile);
52d1313e01SSahid Orentino Ferdjaoui 	if (!obj) {
53d1313e01SSahid Orentino Ferdjaoui 		err = -errno;
549406b485SYonghong Song 		p_err("can't open objfile %s", objfile);
55d8793acaSYonghong Song 		goto close_map_fd;
569406b485SYonghong Song 	}
579406b485SYonghong Song 
589406b485SYonghong Song 	err = bpf_object__load(obj);
599406b485SYonghong Song 	if (err) {
609406b485SYonghong Song 		p_err("can't load objfile %s", objfile);
619406b485SYonghong Song 		goto close_obj;
629406b485SYonghong Song 	}
639406b485SYonghong Song 
646f2b219bSHengqi Chen 	prog = bpf_object__next_program(obj, NULL);
659406b485SYonghong Song 	if (!prog) {
66d1313e01SSahid Orentino Ferdjaoui 		err = -errno;
679406b485SYonghong Song 		p_err("can't find bpf program in objfile %s", objfile);
689406b485SYonghong Song 		goto close_obj;
699406b485SYonghong Song 	}
709406b485SYonghong Song 
71d8793acaSYonghong Song 	link = bpf_program__attach_iter(prog, &iter_opts);
72d1313e01SSahid Orentino Ferdjaoui 	if (!link) {
73d1313e01SSahid Orentino Ferdjaoui 		err = -errno;
749406b485SYonghong Song 		p_err("attach_iter failed for program %s",
759406b485SYonghong Song 		      bpf_program__name(prog));
769406b485SYonghong Song 		goto close_obj;
779406b485SYonghong Song 	}
789406b485SYonghong Song 
79*478a535aSSahil Siddiq 	err = mount_bpffs_for_file(path);
809406b485SYonghong Song 	if (err)
819406b485SYonghong Song 		goto close_link;
829406b485SYonghong Song 
839406b485SYonghong Song 	err = bpf_link__pin(link, path);
849406b485SYonghong Song 	if (err) {
859406b485SYonghong Song 		p_err("pin_iter failed for program %s to path %s",
869406b485SYonghong Song 		      bpf_program__name(prog), path);
879406b485SYonghong Song 		goto close_link;
889406b485SYonghong Song 	}
899406b485SYonghong Song 
909406b485SYonghong Song close_link:
919406b485SYonghong Song 	bpf_link__destroy(link);
929406b485SYonghong Song close_obj:
939406b485SYonghong Song 	bpf_object__close(obj);
94d8793acaSYonghong Song close_map_fd:
95d8793acaSYonghong Song 	if (map_fd >= 0)
96d8793acaSYonghong Song 		close(map_fd);
979406b485SYonghong Song 	return err;
989406b485SYonghong Song }
999406b485SYonghong Song 
do_help(int argc,char ** argv)1009406b485SYonghong Song static int do_help(int argc, char **argv)
1019406b485SYonghong Song {
1029406b485SYonghong Song 	fprintf(stderr,
103d8793acaSYonghong Song 		"Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"
10490040351SQuentin Monnet 		"       %1$s %2$s help\n"
105c07ba629SQuentin Monnet 		"\n"
106d8793acaSYonghong Song 		"       " HELP_SPEC_MAP "\n"
107c07ba629SQuentin Monnet 		"       " HELP_SPEC_OPTIONS " }\n"
10890040351SQuentin Monnet 		"",
10990040351SQuentin Monnet 		bin_name, "iter");
1109406b485SYonghong Song 
1119406b485SYonghong Song 	return 0;
1129406b485SYonghong Song }
1139406b485SYonghong Song 
1149406b485SYonghong Song static const struct cmd cmds[] = {
1159406b485SYonghong Song 	{ "help",	do_help },
1169406b485SYonghong Song 	{ "pin",	do_pin },
1179406b485SYonghong Song 	{ 0 }
1189406b485SYonghong Song };
1199406b485SYonghong Song 
do_iter(int argc,char ** argv)1209406b485SYonghong Song int do_iter(int argc, char **argv)
1219406b485SYonghong Song {
1229406b485SYonghong Song 	return cmd_select(cmds, argc, argv, do_help);
1239406b485SYonghong Song }
124