linux/kernel/bpf/preload/iterators/iterators.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2020 Facebook */
   3#include <argp.h>
   4#include <stdio.h>
   5#include <stdlib.h>
   6#include <string.h>
   7#include <unistd.h>
   8#include <fcntl.h>
   9#include <sys/resource.h>
  10#include <bpf/libbpf.h>
  11#include <bpf/bpf.h>
  12#include <sys/mount.h>
  13#include "iterators.skel.h"
  14#include "bpf_preload_common.h"
  15
  16int to_kernel = -1;
  17int from_kernel = 0;
  18
  19static int send_link_to_kernel(struct bpf_link *link, const char *link_name)
  20{
  21        struct bpf_preload_info obj = {};
  22        struct bpf_link_info info = {};
  23        __u32 info_len = sizeof(info);
  24        int err;
  25
  26        err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &info, &info_len);
  27        if (err)
  28                return err;
  29        obj.link_id = info.id;
  30        if (strlen(link_name) >= sizeof(obj.link_name))
  31                return -E2BIG;
  32        strcpy(obj.link_name, link_name);
  33        if (write(to_kernel, &obj, sizeof(obj)) != sizeof(obj))
  34                return -EPIPE;
  35        return 0;
  36}
  37
  38int main(int argc, char **argv)
  39{
  40        struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
  41        struct iterators_bpf *skel;
  42        int err, magic;
  43        int debug_fd;
  44
  45        debug_fd = open("/dev/console", O_WRONLY | O_NOCTTY | O_CLOEXEC);
  46        if (debug_fd < 0)
  47                return 1;
  48        to_kernel = dup(1);
  49        close(1);
  50        dup(debug_fd);
  51        /* now stdin and stderr point to /dev/console */
  52
  53        read(from_kernel, &magic, sizeof(magic));
  54        if (magic != BPF_PRELOAD_START) {
  55                printf("bad start magic %d\n", magic);
  56                return 1;
  57        }
  58        setrlimit(RLIMIT_MEMLOCK, &rlim);
  59        /* libbpf opens BPF object and loads it into the kernel */
  60        skel = iterators_bpf__open_and_load();
  61        if (!skel) {
  62                /* iterators.skel.h is little endian.
  63                 * libbpf doesn't support automatic little->big conversion
  64                 * of BPF bytecode yet.
  65                 * The program load will fail in such case.
  66                 */
  67                printf("Failed load could be due to wrong endianness\n");
  68                return 1;
  69        }
  70        err = iterators_bpf__attach(skel);
  71        if (err)
  72                goto cleanup;
  73
  74        /* send two bpf_link IDs with names to the kernel */
  75        err = send_link_to_kernel(skel->links.dump_bpf_map, "maps.debug");
  76        if (err)
  77                goto cleanup;
  78        err = send_link_to_kernel(skel->links.dump_bpf_prog, "progs.debug");
  79        if (err)
  80                goto cleanup;
  81
  82        /* The kernel will proceed with pinnging the links in bpffs.
  83         * UMD will wait on read from pipe.
  84         */
  85        read(from_kernel, &magic, sizeof(magic));
  86        if (magic != BPF_PRELOAD_END) {
  87                printf("bad final magic %d\n", magic);
  88                err = -EINVAL;
  89        }
  90cleanup:
  91        iterators_bpf__destroy(skel);
  92
  93        return err != 0;
  94}
  95