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