Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
0002 // Copyright (C) 2020 Facebook
0003 
0004 #define _GNU_SOURCE
0005 #include <unistd.h>
0006 #include <linux/err.h>
0007 #include <bpf/libbpf.h>
0008 
0009 #include "main.h"
0010 
0011 static int do_pin(int argc, char **argv)
0012 {
0013     DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts);
0014     union bpf_iter_link_info linfo;
0015     const char *objfile, *path;
0016     struct bpf_program *prog;
0017     struct bpf_object *obj;
0018     struct bpf_link *link;
0019     int err = -1, map_fd = -1;
0020 
0021     if (!REQ_ARGS(2))
0022         usage();
0023 
0024     objfile = GET_ARG();
0025     path = GET_ARG();
0026 
0027     /* optional arguments */
0028     if (argc) {
0029         if (is_prefix(*argv, "map")) {
0030             NEXT_ARG();
0031 
0032             if (!REQ_ARGS(2)) {
0033                 p_err("incorrect map spec");
0034                 return -1;
0035             }
0036 
0037             map_fd = map_parse_fd(&argc, &argv);
0038             if (map_fd < 0)
0039                 return -1;
0040 
0041             memset(&linfo, 0, sizeof(linfo));
0042             linfo.map.map_fd = map_fd;
0043             iter_opts.link_info = &linfo;
0044             iter_opts.link_info_len = sizeof(linfo);
0045         }
0046     }
0047 
0048     obj = bpf_object__open(objfile);
0049     err = libbpf_get_error(obj);
0050     if (err) {
0051         p_err("can't open objfile %s", objfile);
0052         goto close_map_fd;
0053     }
0054 
0055     err = bpf_object__load(obj);
0056     if (err) {
0057         p_err("can't load objfile %s", objfile);
0058         goto close_obj;
0059     }
0060 
0061     prog = bpf_object__next_program(obj, NULL);
0062     if (!prog) {
0063         p_err("can't find bpf program in objfile %s", objfile);
0064         goto close_obj;
0065     }
0066 
0067     link = bpf_program__attach_iter(prog, &iter_opts);
0068     err = libbpf_get_error(link);
0069     if (err) {
0070         p_err("attach_iter failed for program %s",
0071               bpf_program__name(prog));
0072         goto close_obj;
0073     }
0074 
0075     err = mount_bpffs_for_pin(path);
0076     if (err)
0077         goto close_link;
0078 
0079     err = bpf_link__pin(link, path);
0080     if (err) {
0081         p_err("pin_iter failed for program %s to path %s",
0082               bpf_program__name(prog), path);
0083         goto close_link;
0084     }
0085 
0086 close_link:
0087     bpf_link__destroy(link);
0088 close_obj:
0089     bpf_object__close(obj);
0090 close_map_fd:
0091     if (map_fd >= 0)
0092         close(map_fd);
0093     return err;
0094 }
0095 
0096 static int do_help(int argc, char **argv)
0097 {
0098     fprintf(stderr,
0099         "Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"
0100         "       %1$s %2$s help\n"
0101         "\n"
0102         "       " HELP_SPEC_MAP "\n"
0103         "       " HELP_SPEC_OPTIONS " }\n"
0104         "",
0105         bin_name, "iter");
0106 
0107     return 0;
0108 }
0109 
0110 static const struct cmd cmds[] = {
0111     { "help",   do_help },
0112     { "pin",    do_pin },
0113     { 0 }
0114 };
0115 
0116 int do_iter(int argc, char **argv)
0117 {
0118     return cmd_select(cmds, argc, argv, do_help);
0119 }