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