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